From 09dc942d3e38c09bda56b63769e281de25f7c717 Mon Sep 17 00:00:00 2001 From: netromnetrom <35839198+netromnetrom@users.noreply.github.com> Date: Tue, 5 Feb 2019 16:53:35 +0100 Subject: [PATCH 01/23] Create km-00000406.ini --- instfiles/km-00000406.ini | 659 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 659 insertions(+) create mode 100644 instfiles/km-00000406.ini diff --git a/instfiles/km-00000406.ini b/instfiles/km-00000406.ini new file mode 100644 index 00000000..d99ac820 --- /dev/null +++ b/instfiles/km-00000406.ini @@ -0,0 +1,659 @@ +[noshift] +Key8=0:0 +Key9=65307:27 +Key10=49:49 +Key11=50:50 +Key12=51:51 +Key13=52:52 +Key14=53:53 +Key15=54:54 +Key16=55:55 +Key17=56:56 +Key18=57:57 +Key19=48:48 +Key20=43:43 +Key21=65105:180 +Key22=65288:8 +Key23=65289:9 +Key24=113:113 +Key25=119:119 +Key26=101:101 +Key27=114:114 +Key28=116:116 +Key29=121:121 +Key30=117:117 +Key31=105:105 +Key32=111:111 +Key33=112:112 +Key34=229:229 +Key35=168:168 +Key36=65293:13 +Key37=65507:0 +Key38=97:97 +Key39=115:115 +Key40=100:100 +Key41=102:102 +Key42=103:103 +Key43=104:104 +Key44=106:106 +Key45=107:107 +Key46=108:108 +Key47=230:230 +Key48=248:248 +Key49=189:189 +Key50=65505:0 +Key51=39:39 +Key52=122:122 +Key53=120:120 +Key54=99:99 +Key55=118:118 +Key56=98:98 +Key57=110:110 +Key58=109:109 +Key59=44:44 +Key60=46:46 +Key61=45:45 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=65406:0 +Key94=60:60 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65027:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=0:0 +Key135=0:0 +Key136=0:0 +Key137=0:0 + +[shift] +Key8=0:0 +Key9=65307:27 +Key10=33:33 +Key11=34:34 +Key12=35:35 +Key13=164:164 +Key14=37:37 +Key15=38:38 +Key16=47:47 +Key17=40:40 +Key18=41:41 +Key19=61:61 +Key20=63:63 +Key21=65104:96 +Key22=65288:8 +Key23=65056:0 +Key24=81:81 +Key25=87:87 +Key26=69:69 +Key27=82:82 +Key28=84:84 +Key29=89:89 +Key30=85:85 +Key31=73:73 +Key32=79:79 +Key33=80:80 +Key34=197:197 +Key35=94:94 +Key36=65293:13 +Key37=65507:0 +Key38=65:65 +Key39=83:83 +Key40=68:68 +Key41=70:70 +Key42=71:71 +Key43=72:72 +Key44=74:74 +Key45=75:75 +Key46=76:76 +Key47=198:198 +Key48=216:216 +Key49=167:167 +Key50=65505:0 +Key51=42:42 +Key52=90:90 +Key53=88:88 +Key54=67:67 +Key55=86:86 +Key56=66:66 +Key57=78:78 +Key58=77:77 +Key59=59:59 +Key60=58:58 +Key61=95:95 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65273:0 +Key78=65300:0 +Key79=65463:55 +Key80=65464:56 +Key81=65465:57 +Key82=65453:45 +Key83=65460:52 +Key84=65461:53 +Key85=65462:54 +Key86=65451:43 +Key87=65457:49 +Key88=65458:50 +Key89=65459:51 +Key90=65456:48 +Key91=65452:44 +Key92=0:0 +Key93=65406:0 +Key94=62:62 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65027:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=65469:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=0:0 +Key135=0:0 +Key136=0:0 +Key137=0:0 + +[altgr] +Key8=0:0 +Key9=65307:27 +Key10=161:161 +Key11=64:64 +Key12=163:163 +Key13=36:36 +Key14=8364:8364 +Key15=165:165 +Key16=123:123 +Key17=91:91 +Key18=93:93 +Key19=125:125 +Key20=92:92 +Key21=124:124 +Key22=65288:8 +Key23=65289:9 +Key24=64:64 +Key25=435:322 +Key26=8364:8364 +Key27=174:174 +Key28=254:254 +Key29=2299:8592 +Key30=2302:8595 +Key31=2301:8594 +Key32=5053:339 +Key33=254:254 +Key34=65111:168 +Key35=126:126 +Key36=65293:13 +Key37=65507:0 +Key38=170:170 +Key39=223:223 +Key40=240:240 +Key41=496:273 +Key42=959:331 +Key43=689:295 +Key44=106:106 +Key45=930:312 +Key46=435:322 +Key47=248:248 +Key48=230:230 +Key49=182:182 +Key50=65505:0 +Key51=180:180 +Key52=171:171 +Key53=187:187 +Key54=169:169 +Key55=2770:8220 +Key56=2771:8221 +Key57=110:110 +Key58=181:181 +Key59=65115:184 +Key60=183:183 +Key61=65120:0 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=65406:0 +Key94=92:92 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=0:0 +Key112=65455:47 +Key113=65027:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=0:0 +Key135=0:0 +Key136=0:0 +Key137=0:0 + +[capslock] +Key8=0:0 +Key9=65307:27 +Key10=49:49 +Key11=50:50 +Key12=51:51 +Key13=52:52 +Key14=53:53 +Key15=54:54 +Key16=55:55 +Key17=56:56 +Key18=57:57 +Key19=48:48 +Key20=43:43 +Key21=65105:180 +Key22=65288:8 +Key23=65289:9 +Key24=81:81 +Key25=87:87 +Key26=69:69 +Key27=82:82 +Key28=84:84 +Key29=89:89 +Key30=85:85 +Key31=73:73 +Key32=79:79 +Key33=80:80 +Key34=197:197 +Key35=65111:168 +Key36=65293:13 +Key37=65507:0 +Key38=65:65 +Key39=83:83 +Key40=68:68 +Key41=70:70 +Key42=71:71 +Key43=72:72 +Key44=74:74 +Key45=75:75 +Key46=76:76 +Key47=214:214 +Key48=196:196 +Key49=167:167 +Key50=65505:0 +Key51=39:39 +Key52=90:90 +Key53=88:88 +Key54=67:67 +Key55=86:86 +Key56=66:66 +Key57=78:78 +Key58=77:77 +Key59=44:44 +Key60=46:46 +Key61=45:45 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=65406:0 +Key94=60:60 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65027:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=0:0 +Key135=0:0 +Key136=0:0 +Key137=0:0 + +[shiftcapslock] +Key8=0:0 +Key9=65307:27 +Key10=33:33 +Key11=34:34 +Key12=35:35 +Key13=164:164 +Key14=37:37 +Key15=38:38 +Key16=47:47 +Key17=40:40 +Key18=41:41 +Key19=61:61 +Key20=63:63 +Key21=65104:96 +Key22=65288:8 +Key23=65056:0 +Key24=113:113 +Key25=119:119 +Key26=101:101 +Key27=114:114 +Key28=116:116 +Key29=121:121 +Key30=117:117 +Key31=105:105 +Key32=111:111 +Key33=112:112 +Key34=229:229 +Key35=65106:94 +Key36=65293:13 +Key37=65507:0 +Key38=97:97 +Key39=115:115 +Key40=100:100 +Key41=102:102 +Key42=103:103 +Key43=104:104 +Key44=106:106 +Key45=107:107 +Key46=108:108 +Key47=246:246 +Key48=228:228 +Key49=189:189 +Key50=65505:0 +Key51=42:42 +Key52=122:122 +Key53=120:120 +Key54=99:99 +Key55=118:118 +Key56=98:98 +Key57=110:110 +Key58=109:109 +Key59=59:59 +Key60=58:58 +Key61=95:95 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65273:0 +Key78=65300:0 +Key79=65463:55 +Key80=65464:56 +Key81=65465:57 +Key82=65453:45 +Key83=65460:52 +Key84=65461:53 +Key85=65462:54 +Key86=65451:43 +Key87=65457:49 +Key88=65458:50 +Key89=65459:51 +Key90=65456:48 +Key91=65452:44 +Key92=0:0 +Key93=65406:0 +Key94=62:62 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65027:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=65469:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=0:0 +Key135=0:0 +Key136=0:0 +Key137=0:0 From ee1c24dd47d895d843be297af87556f615fa7ea7 Mon Sep 17 00:00:00 2001 From: netromnetrom <35839198+netromnetrom@users.noreply.github.com> Date: Tue, 5 Feb 2019 16:54:38 +0100 Subject: [PATCH 02/23] Update Makefile.am --- instfiles/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am index e393bb5f..e699b7f4 100644 --- a/instfiles/Makefile.am +++ b/instfiles/Makefile.am @@ -30,6 +30,7 @@ SUFFIXES = .in startscriptdir=$(sysconfdir)/xrdp dist_startscript_DATA = \ + km-00000406.ini \ km-00000407.ini \ km-00000409.ini \ km-0000040a.ini \ From 3f42e5d6e57e3fe49baee4b99e1cf1fbf2644800 Mon Sep 17 00:00:00 2001 From: netromnetrom <35839198+netromnetrom@users.noreply.github.com> Date: Tue, 5 Feb 2019 17:00:46 +0100 Subject: [PATCH 03/23] Add Danish keyboard --- xrdp/xrdp_keyboard.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini index df267991..e0d7c6da 100644 --- a/xrdp/xrdp_keyboard.ini +++ b/xrdp/xrdp_keyboard.ini @@ -59,6 +59,7 @@ layouts_map=default_layouts_map [default_rdp_layouts] rdp_layout_us=0x00000409 rdp_layout_us_dvorak=0x00010409 +rdp_layout_dk=0x00000406 rdp_layout_de=0x00000407 rdp_layout_es=0x0000040A rdp_layout_fi=0x0000040B @@ -84,6 +85,7 @@ rdp_layout_pt=0x00000816 [default_layouts_map] rdp_layout_us=us rdp_layout_us_dvorak=dvorak +rdp_layout_dk=dk rdp_layout_de=de rdp_layout_es=es rdp_layout_fi=fi @@ -120,6 +122,7 @@ layouts_map=default_layouts_map [rdp_layouts_map_mac] rdp_layout_us=us rdp_layout_us_dvorak=dvorak +rdp_layout_dk=dk rdp_layout_de=de rdp_layout_es=es rdp_layout_fi=fi From e655fe6a1b2245aa9f8e1e390f8fd7f18c71f64b Mon Sep 17 00:00:00 2001 From: "4680414@qq.com" <4680414@qq.com> Date: Fri, 15 Feb 2019 09:18:37 +0800 Subject: [PATCH 04/23] =?UTF-8?q?libscp=20v1=20server=20set=20height=20twi?= =?UTF-8?q?ce=EF=BC=8Cand=20not=20set=20width.=20so=20fix=20it.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sesman/libscp/libscp_v1s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index 0e72ea1b..27e5ef13 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -133,7 +133,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES in_uint16_be(c->in_s, cmd); scp_session_set_height(session, cmd); in_uint16_be(c->in_s, cmd); - scp_session_set_height(session, cmd); + scp_session_set_width(session, cmd); in_uint8(c->in_s, sz); if (0 != scp_session_set_bpp(session, sz)) { From 0d8a49ab13aa0444e68b0a3c1d9506220c166cb0 Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Tue, 26 Feb 2019 07:40:10 +0100 Subject: [PATCH 05/23] astyle formatting for sesman config.h and chansrv clipboard --- sesman/chansrv/clipboard.c | 271 +++++++++++++++++++------------------ sesman/config.c | 10 +- 2 files changed, 141 insertions(+), 140 deletions(-) diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index a690e5e2..cf09b9b0 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -185,38 +185,38 @@ x-special/gnome-copied-files #define LOG_LEVEL LOG_ERROR #define log_error(_params...) \ -{ \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} + { \ + g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \ + g_time3(), __func__, __LINE__); \ + g_writeln (_params); \ + } #define log_always(_params...) \ -{ \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} + { \ + g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \ + g_time3(), __func__, __LINE__); \ + g_writeln (_params); \ + } #define log_info(_params...) \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} + { \ + if (LOG_INFO <= LOG_LEVEL) \ + { \ + g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ + g_time3(), __func__, __LINE__); \ + g_writeln (_params); \ + } \ + } #define log_debug(_params...) \ -{ \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} + { \ + if (LOG_DEBUG <= LOG_LEVEL) \ + { \ + g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ + g_time3(), __func__, __LINE__); \ + g_writeln (_params); \ + } \ + } static char g_bmp_image_header[] = { @@ -286,10 +286,10 @@ static int g_file_format_id = -1; static char g_last_atom_name[256] = ""; /*****************************************************************************/ -static char* +static char * get_atom_text(Atom atom) { - char* name; + char *name; int failed; failed = 0; @@ -405,10 +405,10 @@ clipboard_init(void) if (rv == 0) { log_debug("clipboard_init: g_xfixes_event_base %d", - g_xfixes_event_base); + g_xfixes_event_base); st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); log_debug("clipboard_init st %d, maj %d min %d", st, - ver_maj, ver_min); + ver_maj, ver_min); g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", False); g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", @@ -428,7 +428,7 @@ clipboard_init(void) if (g_image_bmp_atom == None) { log_error("clipboard_init: g_image_bmp_atom was " - "not allocated"); + "not allocated"); } g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), @@ -463,12 +463,12 @@ clipboard_init(void) s_mark_end(s); size = (int)(s->end - s->data); log_debug("clipboard_init: data out, sending " - "CB_CLIP_CAPS (clip_msg_id = 1)"); + "CB_CLIP_CAPS (clip_msg_id = 1)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); if (rv != 0) { log_error("clipboard_init: send_channel_data failed " - "rv = %d", rv); + "rv = %d", rv); rv = 4; } } @@ -484,12 +484,12 @@ clipboard_init(void) s_mark_end(s); size = (int)(s->end - s->data); log_debug("clipboard_init: data out, sending " - "CB_MONITOR_READY (clip_msg_id = 1)"); + "CB_MONITOR_READY (clip_msg_id = 1)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); if (rv != 0) { log_error("clipboard_init: send_channel_data failed " - "rv = %d", rv); + "rv = %d", rv); rv = 4; } } @@ -554,7 +554,7 @@ clipboard_send_data_request(int format_id) s_mark_end(s); size = (int)(s->end - s->data); log_debug("clipboard_send_data_request: data out, sending " - "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"); + "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); return rv; @@ -577,7 +577,7 @@ clipboard_send_format_ack(void) s_mark_end(s); size = (int)(s->end - s->data); log_debug("clipboard_send_format_ack: data out, sending " - "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"); + "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); return rv; @@ -715,7 +715,7 @@ clipboard_send_format_announce(int xrdp_clip_type) break; default: log_debug("clipboard_send_format_announce: unknown " - "xrdp_clip_type %d", xrdp_clip_type); + "xrdp_clip_type %d", xrdp_clip_type); break; } } @@ -759,7 +759,7 @@ clipboard_send_format_announce(int xrdp_clip_type) break; default: log_debug("clipboard_send_format_announce: unknown " - "xrdp_clip_type %d", xrdp_clip_type); + "xrdp_clip_type %d", xrdp_clip_type); break; } } @@ -774,7 +774,7 @@ clipboard_send_format_announce(int xrdp_clip_type) size = (int)(s->end - s->data); //g_hexdump(s->data, size); log_debug("clipboard_send_format_announce: data out, sending " - "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"); + "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); return rv; @@ -789,7 +789,7 @@ clipboard_send_data_response_for_image(const char *data, int data_size) int rv; log_debug("clipboard_send_data_response_for_image: data_size %d", - data_size); + data_size); make_stream(s); init_stream(s, 64 + data_size); out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */ @@ -814,17 +814,17 @@ clipboard_send_data_response_for_text(const char *data, int data_size) int num_chars; log_debug("clipboard_send_data_response_for_text: data_size %d", - data_size); + data_size); //g_hexdump(data, data_size); num_chars = g_mbstowcs(0, data, 0); if (num_chars < 0) { log_error("clipboard_send_data_response_for_text: " - "bad string"); + "bad string"); num_chars = 0; } log_debug("clipboard_send_data_response_for_text: data_size %d " - "num_chars %d", data_size, num_chars); + "num_chars %d", data_size, num_chars); make_stream(s); init_stream(s, 64 + num_chars * 2); out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */ @@ -833,15 +833,15 @@ clipboard_send_data_response_for_text(const char *data, int data_size) if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2) { log_error("clipboard_send_data_response_for_text: error " - "clipboard_out_unicode didn't write right number of bytes"); + "clipboard_out_unicode didn't write right number of bytes"); } out_uint16_le(s, 0); /* nil for string */ out_uint32_le(s, 0); s_mark_end(s); size = (int)(s->end - s->data); log_debug("clipboard_send_data_response_for_text: data out, " - "sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d " - "num_chars %d", size, num_chars); + "sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d " + "num_chars %d", size, num_chars); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); return rv; @@ -869,7 +869,7 @@ clipboard_send_data_response(int xrdp_clip_type, const char *data, int data_size else { log_debug("clipboard_send_data_response: unknown " - "xrdp_clip_type %d", xrdp_clip_type); + "xrdp_clip_type %d", xrdp_clip_type); } } else @@ -908,7 +908,7 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type) long val1[2]; log_debug("clipboard_provide_selection_c2s: bytes %d", - g_clip_c2s.total_bytes); + g_clip_c2s.total_bytes); if (g_clip_c2s.total_bytes < g_incr_max_req_size) { XChangeProperty(g_display, req->requestor, req->property, @@ -934,8 +934,8 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type) g_clip_c2s.property = req->property; g_clip_c2s.window = req->requestor; log_debug("clipboard_provide_selection_c2s: start INCR property %s " - "type %s", get_atom_text(req->property), - get_atom_text(type)); + "type %s", get_atom_text(req->property), + get_atom_text(type)); val1[0] = g_clip_c2s.total_bytes; val1[1] = 0; XChangeProperty(g_display, req->requestor, req->property, @@ -1020,7 +1020,7 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, char *holdp; log_debug("clipboard_process_format_announce: " - "CLIPRDR_FORMAT_ANNOUNCE"); + "CLIPRDR_FORMAT_ANNOUNCE"); log_debug("clipboard_process_format_announce %d", clip_msg_len); clipboard_send_format_ack(); @@ -1052,8 +1052,8 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, clip_msg_len -= 32; } log_debug("clipboard_process_format_announce: formatId 0x%8.8x " - "wszFormatName [%s] clip_msg_len %d", formatId, desc, - clip_msg_len); + "wszFormatName [%s] clip_msg_len %d", formatId, desc, + clip_msg_len); if (g_num_formatIds <= 15) { g_formatIds[g_num_formatIds] = formatId; @@ -1073,13 +1073,13 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, } if ((g_num_formatIds > 0) && - (g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */ - (g_clip_s2c.incr_in_progress == 0)) + (g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */ + (g_clip_s2c.incr_in_progress == 0)) { if (clipboard_set_selection_owner() != 0) { log_error("clipboard_process_format_announce: " - "XSetSelectionOwner failed"); + "XSetSelectionOwner failed"); } } @@ -1130,7 +1130,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, int requestedFormatId; log_debug("clipboard_process_data_request: " - "CLIPRDR_DATA_REQUEST"); + "CLIPRDR_DATA_REQUEST"); log_debug("clipboard_process_data_request:"); log_debug(" %d", g_clip_s2c.xrdp_clip_type); in_uint32_le(s, requestedFormatId); @@ -1146,7 +1146,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, else { log_debug("clipboard_process_data_request: CB_FORMAT_FILE, " - "calling XConvertSelection to g_utf8_atom"); + "calling XConvertSelection to g_utf8_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE; XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type, g_clip_property_atom, g_wnd, CurrentTime); @@ -1162,7 +1162,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, else { log_debug("clipboard_process_data_request: CB_FORMAT_DIB, " - "calling XConvertSelection to g_image_bmp_atom"); + "calling XConvertSelection to g_image_bmp_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP; XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, g_clip_property_atom, g_wnd, CurrentTime); @@ -1178,7 +1178,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, else { log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, " - "calling XConvertSelection to g_utf8_atom"); + "calling XConvertSelection to g_utf8_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT; XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, g_clip_property_atom, g_wnd, CurrentTime); @@ -1186,7 +1186,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, break; default: log_debug("clipboard_process_data_request: unknown type %d", - requestedFormatId); + requestedFormatId); clipboard_send_data_response_failed(); break; } @@ -1201,14 +1201,14 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status, clipboard data. */ static int clipboard_process_data_response_for_image(struct stream *s, - int clip_msg_status, - int clip_msg_len) + int clip_msg_status, + int clip_msg_len) { XSelectionRequestEvent *lxev; int len; log_debug("clipboard_process_data_response_for_image: " - "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"); + "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"); lxev = &g_saved_selection_req_event; len = (int)(s->end - s->p); if (len < 1) @@ -1231,7 +1231,7 @@ clipboard_process_data_response_for_image(struct stream *s, g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14); in_uint8a(s, g_clip_c2s.data + 14, len); log_debug("clipboard_process_data_response_for_image: calling " - "clipboard_provide_selection_c2s"); + "clipboard_provide_selection_c2s"); clipboard_provide_selection_c2s(lxev, lxev->target); return 0; } @@ -1259,7 +1259,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status, if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP) { clipboard_process_data_response_for_image(s, clip_msg_status, - clip_msg_len); + clip_msg_len); return 0; } if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE) @@ -1287,7 +1287,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status, return 0; } log_debug("clipboard_process_data_response: " - "CLIPRDR_DATA_RESPONSE"); + "CLIPRDR_DATA_RESPONSE"); len = (int)(s->end - s->p); if (len < 1) { @@ -1362,10 +1362,10 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status, in_uint32_le(s, version); /* version */ in_uint32_le(s, flags); /* generalFlags */ log_debug("clipboard_process_clip_caps: " - "g_cliprdr_version %d version %d " - "g_cliprdr_flags 0x%x flags 0x%x", - g_cliprdr_version, version, - g_cliprdr_flags, flags); + "g_cliprdr_version %d version %d " + "g_cliprdr_flags 0x%x flags 0x%x", + g_cliprdr_version, version, + g_cliprdr_flags, flags); if (version < g_cliprdr_version) { g_cliprdr_version = version; @@ -1374,7 +1374,7 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status, break; default: log_debug("clipboard_process_clip_caps: unknown " - "capabilitySetType %d", capabilitySetType); + "capabilitySetType %d", capabilitySetType); break; } s->p = holdp + lengthCapability; @@ -1552,16 +1552,16 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, if (!g_clip_up) { log_error("aborting clipboard_data_in - clipboard has not " - "been initialized"); + "been initialized"); /* we return 0 here to indicate no protocol problem occurred */ return 0; } log_debug("clipboard_data_in: chan_id %d " - "chan_flags 0x%x length %d total_length %d " - "in_request %d g_ins->size %d", - chan_id, chan_flags, length, total_length, - g_clip_c2s.in_request, g_ins->size); + "chan_flags 0x%x length %d total_length %d " + "in_request %d g_ins->size %d", + chan_id, chan_flags, length, total_length, + g_clip_c2s.in_request, g_ins->size); if (g_clip_c2s.doing_response_ss) { @@ -1621,37 +1621,37 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, in_uint32_le(ls, clip_msg_len); log_debug("clipboard_data_in: clip_msg_id %d " - "clip_msg_status %d clip_msg_len %d", - clip_msg_id, clip_msg_status, clip_msg_len); + "clip_msg_status %d clip_msg_len %d", + clip_msg_id, clip_msg_status, clip_msg_len); rv = 0; log_debug("clipboard_data_in: %d", clip_msg_id); switch (clip_msg_id) { - /* sent by client or server when its local system clipboard is */ - /* updated with new clipboard data; contains Clipboard Format ID */ - /* and name pairs of new Clipboard Formats on the clipboard. */ + /* sent by client or server when its local system clipboard is */ + /* updated with new clipboard data; contains Clipboard Format ID */ + /* and name pairs of new Clipboard Formats on the clipboard. */ case CB_FORMAT_LIST: /* 2 CLIPRDR_FORMAT_ANNOUNCE */ rv = clipboard_process_format_announce(ls, clip_msg_status, clip_msg_len); break; - /* response to CB_FORMAT_LIST; used to indicate whether */ - /* processing of the Format List PDU was successful */ + /* response to CB_FORMAT_LIST; used to indicate whether */ + /* processing of the Format List PDU was successful */ case CB_FORMAT_LIST_RESPONSE: /* 3 CLIPRDR_FORMAT_ACK */ rv = clipboard_process_format_ack(ls, clip_msg_status, clip_msg_len); break; - /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ - /* of the formats that was listed in CB_FORMAT_LIST */ + /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ + /* of the formats that was listed in CB_FORMAT_LIST */ case CB_FORMAT_DATA_REQUEST: /* 4 CLIPRDR_DATA_REQUEST */ rv = clipboard_process_data_request(ls, clip_msg_status, clip_msg_len); break; - /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ - /* whether processing of the CB_FORMAT_DATA_REQUEST was */ - /* successful; if processing was successful, */ - /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ - /* clipboard data. */ + /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ + /* whether processing of the CB_FORMAT_DATA_REQUEST was */ + /* successful; if processing was successful, */ + /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ + /* clipboard data. */ case CB_FORMAT_DATA_RESPONSE: /* 5 CLIPRDR_DATA_RESPONSE */ rv = clipboard_process_data_response(ls, clip_msg_status, clip_msg_len); @@ -1671,7 +1671,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, default: log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id); log_error("clipboard_data_in: unknown clip_msg_id %d", - clip_msg_id); + clip_msg_id); break; } @@ -1703,21 +1703,22 @@ clipboard_event_selection_owner_notify(XEvent *xevent) lxevent = (XFixesSelectionNotifyEvent *)xevent; log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner); log_debug("clipboard_event_selection_owner_notify: " - "window %ld subtype %d owner %ld g_wnd %ld", - lxevent->window, lxevent->subtype, lxevent->owner, g_wnd); + "window %ld subtype %d owner %ld g_wnd %ld", + lxevent->window, lxevent->subtype, lxevent->owner, g_wnd); if (lxevent->owner == g_wnd) { log_debug("clipboard_event_selection_owner_notify: matches g_wnd"); log_debug("clipboard_event_selection_owner_notify: skipping, " - "owner == g_wnd"); + "owner == g_wnd"); g_got_selection = 1; return 0; } g_got_selection = 0; if (lxevent->owner != 0) /* nil owner comes when selection */ - { /* window is closed */ + { + /* window is closed */ XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, g_clip_property_atom, g_wnd, lxevent->timestamp); } @@ -1871,22 +1872,22 @@ clipboard_event_selection_notify(XEvent *xevent) if (lxevent->property == None) { log_error("clipboard_event_selection_notify: clip could " - "not be converted"); + "not be converted"); rv = 1; } if (rv == 0) { log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s", - lxevent->requestor, - get_atom_text(lxevent->property)); + lxevent->requestor, + get_atom_text(lxevent->property)); rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, &type, &fmt, &n_items, &data, &data_size); if (rv != 0) { log_error("clipboard_event_selection_notify: " - "clipboard_get_window_property failed error %d", rv); + "clipboard_get_window_property failed error %d", rv); return 0; } //g_hexdump(data, data_size); @@ -1896,9 +1897,9 @@ clipboard_event_selection_notify(XEvent *xevent) /* nothing more to do here, the data is coming in through PropertyNotify */ log_debug("clipboard_event_selection_notify: type is INCR " - "data_size %d property name %s type %s", data_size, - get_atom_text(lxevent->property), - get_atom_text(lxevent->type)); + "data_size %d property name %s type %s", data_size, + get_atom_text(lxevent->property), + get_atom_text(lxevent->type)); g_clip_s2c.incr_in_progress = 1; g_clip_s2c.property = lxevent->property; g_clip_s2c.type = lxevent->target; @@ -1928,7 +1929,7 @@ clipboard_event_selection_notify(XEvent *xevent) "clipboard_event_selection_notify: 0x%lx %s 0x%lx", atom, get_atom_text(atom), XA_STRING)); log_debug("clipboard_event_selection_notify: 0x%lx %s", - atom, get_atom_text(atom)); + atom, get_atom_text(atom)); if (atom == g_utf8_atom) { got_utf8 = 1; @@ -1955,16 +1956,16 @@ clipboard_event_selection_notify(XEvent *xevent) else { log_error("clipboard_event_selection_notify: error, " - "target is 'TARGETS' and type[%ld] or fmt[%d] not right, " - "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32); + "target is 'TARGETS' and type[%ld] or fmt[%d] not right, " + "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32); } } else if (lxevent->target == g_utf8_atom) { log_debug("clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size); + "data_size %d", data_size); log_debug("clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size); + "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { g_free(g_clip_s2c.data); @@ -1987,9 +1988,9 @@ clipboard_event_selection_notify(XEvent *xevent) else if (lxevent->target == XA_STRING) { log_debug("clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size); + "data_size %d", data_size); log_debug("clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size); + "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { g_free(g_clip_s2c.data); @@ -2004,9 +2005,9 @@ clipboard_event_selection_notify(XEvent *xevent) else if (lxevent->target == g_image_bmp_atom) { log_debug("clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size); + "data_size %d", data_size); log_debug("clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size); + "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14)) { g_free(g_clip_s2c.data); @@ -2020,9 +2021,9 @@ clipboard_event_selection_notify(XEvent *xevent) else if (lxevent->target == g_file_atom1) { log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); + "data_size %d", data_size); log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); + "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { g_free(g_clip_s2c.data); @@ -2037,9 +2038,9 @@ clipboard_event_selection_notify(XEvent *xevent) else if (lxevent->target == g_file_atom2) { log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); + "data_size %d", data_size); log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); + "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { g_free(g_clip_s2c.data); @@ -2054,13 +2055,13 @@ clipboard_event_selection_notify(XEvent *xevent) else { log_error("clipboard_event_selection_notify: " - "unknown target"); + "unknown target"); } } else { log_error("clipboard_event_selection_notify: " - "unknown selection"); + "unknown selection"); } } @@ -2145,24 +2146,24 @@ clipboard_event_selection_request(XEvent *xevent) lxev = (XSelectionRequestEvent *)xevent; log_debug("clipboard_event_selection_request: 0x%lx", lxev->property); log_debug("clipboard_event_selection_request: g_wnd %ld, " - ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld", - g_wnd, lxev->requestor, lxev->owner, lxev->selection, - get_atom_text(lxev->selection), - lxev->target, lxev->property); + ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld", + g_wnd, lxev->requestor, lxev->owner, lxev->selection, + get_atom_text(lxev->selection), + lxev->target, lxev->property); if (lxev->property == None) { log_debug("clipboard_event_selection_request: lxev->property " - "is None"); + "is None"); log_debug("clipboard_event_selection_request: " - "lxev->property is None"); + "lxev->property is None"); } else if (lxev->target == g_targets_atom) { log_debug("clipboard_event_selection_request: g_targets_atom"); /* requestor is asking what the selection can be converted to */ log_debug("clipboard_event_selection_request: " - "g_targets_atom"); + "g_targets_atom"); atom_buf[0] = g_targets_atom; atom_buf[1] = g_timestamp_atom; atom_buf[2] = g_multiple_atom; @@ -2193,7 +2194,7 @@ clipboard_event_selection_request(XEvent *xevent) { /* requestor is asking the time I got the selection */ log_debug("clipboard_event_selection_request: " - "g_timestamp_atom"); + "g_timestamp_atom"); atom_buf[0] = g_selection_time; atom_buf[1] = 0; return clipboard_provide_selection(lxev, XA_INTEGER, 32, @@ -2203,7 +2204,7 @@ clipboard_event_selection_request(XEvent *xevent) { /* target, property pairs */ log_debug("clipboard_event_selection_request: " - "g_multiple_atom"); + "g_multiple_atom"); xdata = 0; if (clipboard_get_window_property(lxev->requestor, lxev->property, @@ -2211,7 +2212,7 @@ clipboard_event_selection_request(XEvent *xevent) &xdata_size) == 0) { log_debug("clipboard_event_selection_request: g_multiple_atom " - "n_items %d", n_items); + "n_items %d", n_items); /* todo */ g_free(xdata); } @@ -2276,7 +2277,7 @@ clipboard_event_selection_request(XEvent *xevent) else { log_debug("clipboard_event_selection_request: unknown " - "target %s", get_atom_text(lxev->target)); + "target %s", get_atom_text(lxev->target)); LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " "target %s", get_atom_text(lxev->target))); } @@ -2332,9 +2333,9 @@ clipboard_event_property_notify(XEvent *xevent) log_debug("clipboard_event_property_notify:"); log_debug("clipboard_event_property_notify: PropertyNotify .window %ld " - ".state %d .atom %ld %s", xevent->xproperty.window, - xevent->xproperty.state, xevent->xproperty.atom, - get_atom_text(xevent->xproperty.atom)); + ".state %d .atom %ld %s", xevent->xproperty.window, + xevent->xproperty.state, xevent->xproperty.atom, + get_atom_text(xevent->xproperty.atom)); if (g_clip_c2s.incr_in_progress && (xevent->xproperty.window == g_clip_c2s.window) && @@ -2353,7 +2354,7 @@ clipboard_event_property_notify(XEvent *xevent) data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done); data_bytes = g_clip_c2s.read_bytes_done - g_clip_c2s.incr_bytes_done; if ((data_bytes < 1) && - (g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes)) + (g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes)) { g_clip_c2s.incr_in_progress = 0; return 0; @@ -2423,7 +2424,7 @@ clipboard_event_property_notify(XEvent *xevent) else { log_error("clipboard_event_property_notify: error unknown type %ld", - g_clip_s2c.type); + g_clip_s2c.type); clipboard_send_data_response_failed(); } diff --git a/sesman/config.c b/sesman/config.c index 78949995..0f661008 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -481,7 +481,7 @@ config_dump(struct config_sesman *config) g_writeln(" DefaultWindowManager: %s", config->default_wm); g_writeln(" ReconnectScript: %s", config->reconnect_sh); g_writeln(" AuthFilePath: %s", - ((config->auth_file_path) ? (config->auth_file_path) : ("disabled"))); + ((config->auth_file_path) ? (config->auth_file_path) : ("disabled"))); /* Session configuration */ g_writeln("Session configuration:"); @@ -530,7 +530,7 @@ config_dump(struct config_sesman *config) for (i = 0; i < config->xorg_params->count; i++) { g_writeln(" Parameter %02d %s", - i, (char *) list_get_item(config->xorg_params, i)); + i, (char *) list_get_item(config->xorg_params, i)); } /* Xvnc */ @@ -542,7 +542,7 @@ config_dump(struct config_sesman *config) for (i = 0; i < config->vnc_params->count; i++) { g_writeln(" Parameter %02d %s", - i, (char *)list_get_item(config->vnc_params, i)); + i, (char *)list_get_item(config->vnc_params, i)); } /* X11rdp */ @@ -554,7 +554,7 @@ config_dump(struct config_sesman *config) for (i = 0; i < config->rdp_params->count; i++) { g_writeln(" Parameter %02d %s", - i, (char *)list_get_item(config->rdp_params, i)); + i, (char *)list_get_item(config->rdp_params, i)); } /* SessionVariables */ @@ -567,7 +567,7 @@ config_dump(struct config_sesman *config) { g_writeln(" Parameter %02d %s=%s", i, (char *) list_get_item(config->env_names, i), - (char *) list_get_item(config->env_values, i)); + (char *) list_get_item(config->env_values, i)); } } From 751cd970181a6804dfced2a849bd1dd1586bbc54 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamski Date: Mon, 19 Nov 2018 13:04:43 +0100 Subject: [PATCH 06/23] reapply outboud-resitrcted clipboard --- docs/man/sesman.ini.5.in | 6 ++++++ sesman/chansrv/Makefile.am | 5 ++++- sesman/chansrv/clipboard.c | 26 +++++++++++++++++++++++++- sesman/config.c | 9 +++++++++ sesman/config.h | 5 +++++ sesman/sesman.ini.in | 3 +++ 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index 2074985c..29bed60c 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -196,6 +196,12 @@ login for all users is enabled. \fIThis option is currently ignored!\fR Only members of this group can have session management rights. +.TP +\fBRestrictOutboundClipboard\fR=\fI[true|false]\fR +If set to \fB1\fR, \fBtrue\fR or \fByes\fR, will restrict the clipboard +outbound from the server, to prevent data copied inside the xrdp session +to be be pasted in the client host. Default value is \fBfalse\fR. + .TP \fBAlwaysGroupCheck\fR=\fI[true|false]\fR If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am index 05007757..7eb0ce1c 100644 --- a/sesman/chansrv/Makefile.am +++ b/sesman/chansrv/Makefile.am @@ -9,7 +9,9 @@ AM_CPPFLAGS = \ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \ - -I$(top_srcdir)/common + -I$(top_srcdir)/common \ + -I$(top_srcdir)/sesman \ + -I$(top_srcdir)/sesman/libscp if XRDP_DEBUG AM_CPPFLAGS += -DXRDP_DEBUG @@ -54,6 +56,7 @@ xrdp_chansrv_SOURCES = \ clipboard_common.h \ clipboard_file.c \ clipboard_file.h \ + config.c \ devredir.c \ devredir.h \ fifo.c \ diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index cf09b9b0..ae2e34ca 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -170,6 +170,7 @@ x-special/gnome-copied-files #include "parse.h" #include "os_calls.h" #include "chansrv.h" +#include "../config.h" #include "clipboard.h" #include "clipboard_file.h" #include "clipboard_common.h" @@ -229,12 +230,16 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ +struct config_sesman g_cfg /* config.h */ + extern Display *g_display; /* in xcommon.c */ extern int g_x_socket; /* in xcommon.c */ extern tbus g_x_wait_obj; /* in xcommon.c */ extern Screen *g_screen; /* in xcommon.c */ extern int g_screen_num; /* in xcommon.c */ +int g_outbound_clipboard_restricted = 0; + int g_clip_up = 0; static Atom g_clipboard_atom = 0; /* CLIPBOARD */ @@ -376,6 +381,17 @@ clipboard_init(void) return 0; } + if (0 != config_read(&g_cfg)) + { + g_printf("clipboard: error reading config. quitting.\n"); + return 1; + } + + log_debug("clipboard_init: outbound clipboard restricted -> " + g_cfg.sec.restrict_oubound_clipboard) + //one-way clipboard + g_outbound_clipboard_restricted = g_cfg.sec.restrict_oubound_clipboard; + + xfuse_init(); xcommon_init(); g_incr_max_req_size = XMaxRequestSize(g_display) * 4 - 24; @@ -2485,6 +2501,8 @@ clipboard_xevent(void *xevent) { XEvent *lxevent; + log_debug("clipboard_xevent: event detected"); + if (!g_clip_up) { return 1; @@ -2495,7 +2513,13 @@ clipboard_xevent(void *xevent) switch (lxevent->type) { case SelectionNotify: - clipboard_event_selection_notify(lxevent); + if (g_outbound_clipboard_restricted == 0) { + log_debug("clipboard_xevent: clipboard SelectionNotify event on xorg.") + clipboard_event_selection_notify(lxevent); + } else { + log_debug("clipboard_xevent: clipboard restricted, ignoring xorg event.") + return 1; + } break; case SelectionRequest: clipboard_event_selection_request(lxevent); diff --git a/sesman/config.c b/sesman/config.c index 0f661008..4f58f866 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -235,6 +235,7 @@ config_read_security(int file, struct config_security *sc, sc->login_retry = 3; sc->ts_users_enable = 0; sc->ts_admins_enable = 0; + sc->restrict_oubound_clipboard = 0; file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); @@ -273,6 +274,13 @@ config_read_security(int file, struct config_security *sc, { sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i)); } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_RESTRICT_CLIPBOARD)) + { + sc->restrict_oubound_clipboard = g_text2bool((char *)list_get_item(param_v, i)); + } + + } return 0; @@ -497,6 +505,7 @@ config_dump(struct config_sesman *config) g_writeln(" AllowRootLogin: %d", sc->allow_root); g_writeln(" MaxLoginRetry: %d", sc->login_retry); g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check); + g_printf("\tRestrictOutboundClipboard: %i\r\n", sc->restrict_oubound_clipboard); g_printf( " TSUsersGroup: "); if (sc->ts_users_enable) diff --git a/sesman/config.h b/sesman/config.h index 6e63fcef..1ba224c9 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -126,6 +126,11 @@ struct config_security * @brief if the Groups are not found deny access */ int ts_always_group_check; + /** + * @var restrict_oubound_clipboard + * @brief if the clipboard should be enforced restricted. If true only allow client -> server, not vice versa. + */ + int restrict_oubound_clipboard; }; /** diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index 9af7a100..1c3147ad 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -19,6 +19,9 @@ TerminalServerAdmins=tsadmins ; When AlwaysGroupCheck=false access will be permitted ; if the group TerminalServerUsers is not defined. AlwaysGroupCheck=false +; When RestrictOutboundClipboard=true clipboard from the +; server is not pushed to the client. +RestrictOutboundClipboard=false [Sessions] ;; X11DisplayOffset - x11 display number offset From 46c33ddaf402843a3546eb0ae8e6ac4b62da525f Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Tue, 26 Feb 2019 11:36:32 +0100 Subject: [PATCH 07/23] Read sesman config in clipboard --- sesman/chansrv/clipboard.c | 41 +++++++++++++++++++++++--------------- sesman/chansrv/config.c | 1 + sesman/config.c | 8 ++++---- sesman/config.h | 5 +++-- 4 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 sesman/chansrv/config.c diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index ae2e34ca..1d6357da 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -230,7 +230,7 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ -struct config_sesman g_cfg /* config.h */ +struct config_sesman *g_cfg; /* config.h */ extern Display *g_display; /* in xcommon.c */ extern int g_x_socket; /* in xcommon.c */ @@ -381,16 +381,24 @@ clipboard_init(void) return 0; } - if (0 != config_read(&g_cfg)) - { - g_printf("clipboard: error reading config. quitting.\n"); - return 1; - } + /* reading config */ + g_cfg = g_new0(struct config_sesman, 1); - log_debug("clipboard_init: outbound clipboard restricted -> " + g_cfg.sec.restrict_oubound_clipboard) - //one-way clipboard - g_outbound_clipboard_restricted = g_cfg.sec.restrict_oubound_clipboard; + if (0 == g_cfg) + { + g_printf("error creating config: quitting.\n"); + g_deinit(); + g_exit(1); + } + if (0 != config_read(g_cfg)) + { + log_error("clipboard: error reading config. quitting."); + return 1; + } + + //one-way clipboard + g_outbound_clipboard_restricted = g_cfg->sec.restrict_outbound_clipboard; xfuse_init(); xcommon_init(); @@ -2513,13 +2521,14 @@ clipboard_xevent(void *xevent) switch (lxevent->type) { case SelectionNotify: - if (g_outbound_clipboard_restricted == 0) { - log_debug("clipboard_xevent: clipboard SelectionNotify event on xorg.") - clipboard_event_selection_notify(lxevent); - } else { - log_debug("clipboard_xevent: clipboard restricted, ignoring xorg event.") - return 1; - } + if (g_outbound_clipboard_restricted == 0) + { + clipboard_event_selection_notify(lxevent); + } + else + { + return 1; + } break; case SelectionRequest: clipboard_event_selection_request(lxevent); diff --git a/sesman/chansrv/config.c b/sesman/chansrv/config.c new file mode 100644 index 00000000..82a7fbd5 --- /dev/null +++ b/sesman/chansrv/config.c @@ -0,0 +1 @@ +#include "../config.c" \ No newline at end of file diff --git a/sesman/config.c b/sesman/config.c index 4f58f866..a42bb47f 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -235,7 +235,7 @@ config_read_security(int file, struct config_security *sc, sc->login_retry = 3; sc->ts_users_enable = 0; sc->ts_admins_enable = 0; - sc->restrict_oubound_clipboard = 0; + sc->restrict_outbound_clipboard = 0; file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); @@ -274,10 +274,10 @@ config_read_security(int file, struct config_security *sc, { sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i)); } - + if (0 == g_strcasecmp(buf, SESMAN_CFG_RESTRICT_CLIPBOARD)) { - sc->restrict_oubound_clipboard = g_text2bool((char *)list_get_item(param_v, i)); + sc->restrict_outbound_clipboard = g_text2bool((char *)list_get_item(param_v, i)); } @@ -505,7 +505,7 @@ config_dump(struct config_sesman *config) g_writeln(" AllowRootLogin: %d", sc->allow_root); g_writeln(" MaxLoginRetry: %d", sc->login_retry); g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check); - g_printf("\tRestrictOutboundClipboard: %i\r\n", sc->restrict_oubound_clipboard); + g_writeln(" RestrictOutboundClipboard: %d", sc->restrict_outbound_clipboard); g_printf( " TSUsersGroup: "); if (sc->ts_users_enable) diff --git a/sesman/config.h b/sesman/config.h index 1ba224c9..b8e8bc76 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -60,6 +60,7 @@ #define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers" #define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins" #define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck" +#define SESMAN_CFG_RESTRICT_CLIPBOARD "RestrictOutboundClipboard" #define SESMAN_CFG_SESSIONS "Sessions" #define SESMAN_CFG_SESS_MAX "MaxSessions" @@ -127,10 +128,10 @@ struct config_security */ int ts_always_group_check; /** - * @var restrict_oubound_clipboard + * @var restrict_outbound_clipboard * @brief if the clipboard should be enforced restricted. If true only allow client -> server, not vice versa. */ - int restrict_oubound_clipboard; + int restrict_outbound_clipboard; }; /** From d49f4051301231e839c99b2ae1a20f2885508d5d Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Tue, 26 Feb 2019 13:22:30 +0000 Subject: [PATCH 08/23] Add implementation of xfuse_deinit_xrdp_fs() --- sesman/chansrv/chansrv_fuse.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 1095b63e..2eb8efda 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -492,7 +492,6 @@ xfuse_init(void) int xfuse_deinit(void) { - xfuse_deinit_xrdp_fs(); fifo_deinit(&g_fifo_opendir); if (g_ch != 0) @@ -520,6 +519,8 @@ xfuse_deinit(void) g_req_list = 0; } + xfuse_deinit_xrdp_fs(); + g_xfuse_inited = 0; return 0; } @@ -969,6 +970,28 @@ static int xfuse_init_xrdp_fs(void) static int xfuse_deinit_xrdp_fs(void) { + fuse_ino_t i; + struct xrdp_inode *xinode; + + if (g_xrdp_fs.inode_table != NULL) + { + for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; ++i) + { + if ((xinode = g_xrdp_fs.inode_table[i]) != NULL) + { + g_xrdp_fs.inode_table[i] = NULL; + log_debug("Freeing %s",xinode->name); + free(xinode); + } + } + free(g_xrdp_fs.inode_table); + g_xrdp_fs.inode_table = NULL; + } + + g_xrdp_fs.max_entries = 0; + g_xrdp_fs.num_entries = 0; + g_xrdp_fs.next_node = 1; + return 0; } From 1b6bfa682c999804ed424818af516f4a308361d5 Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Fri, 1 Mar 2019 14:46:02 +0100 Subject: [PATCH 09/23] Log when outbound copy was rejected because RestrictOutboundClipboard was set --- sesman/chansrv/clipboard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 1d6357da..5a0854a8 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -2527,6 +2527,7 @@ clipboard_xevent(void *xevent) } else { + log_debug("outbound clipboard is restricted because %s is True in config", SESMAN_CFG_RESTRICT_CLIPBOARD); return 1; } break; From 7d7e8184ae20bffa8ae9c4930d5d896ef6417421 Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Sat, 2 Mar 2019 15:36:56 +0100 Subject: [PATCH 10/23] Use CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD env between sesman -> chansrv --- sesman/chansrv/Makefile.am | 5 +---- sesman/chansrv/chansrv.c | 10 +++++++++- sesman/chansrv/clipboard.c | 28 +++------------------------- sesman/chansrv/config.c | 1 - sesman/session.c | 4 ++++ 5 files changed, 17 insertions(+), 31 deletions(-) delete mode 100644 sesman/chansrv/config.c diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am index 7eb0ce1c..05007757 100644 --- a/sesman/chansrv/Makefile.am +++ b/sesman/chansrv/Makefile.am @@ -9,9 +9,7 @@ AM_CPPFLAGS = \ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/sesman \ - -I$(top_srcdir)/sesman/libscp + -I$(top_srcdir)/common if XRDP_DEBUG AM_CPPFLAGS += -DXRDP_DEBUG @@ -56,7 +54,6 @@ xrdp_chansrv_SOURCES = \ clipboard_common.h \ clipboard_file.c \ clipboard_file.h \ - config.c \ devredir.c \ devredir.h \ fifo.c \ diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 7a0de556..3d5ed08f 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -59,6 +59,7 @@ int g_cliprdr_chan_id = -1; /* cliprdr */ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ +int g_restrict_outbound_clipboard = 0; char *g_exec_name; tbus g_exec_event; @@ -1780,7 +1781,7 @@ main(int argc, char **argv) enum logReturns error; struct log_config logconfig; enum logLevels log_level; - + char *restrict_outbound_clipboard_env; g_init("xrdp-chansrv"); /* os_calls */ log_path[255] = 0; @@ -1791,6 +1792,13 @@ main(int argc, char **argv) return 1; } + restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD"); + if (restrict_outbound_clipboard_env != 0) { + if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0) { + g_restrict_outbound_clipboard = 1; + } + } + read_ini(); pid = g_getpid(); display_text = g_getenv("DISPLAY"); diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 5a0854a8..834fe051 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -170,7 +170,6 @@ x-special/gnome-copied-files #include "parse.h" #include "os_calls.h" #include "chansrv.h" -#include "../config.h" #include "clipboard.h" #include "clipboard_file.h" #include "clipboard_common.h" @@ -230,15 +229,13 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ -struct config_sesman *g_cfg; /* config.h */ - extern Display *g_display; /* in xcommon.c */ extern int g_x_socket; /* in xcommon.c */ extern tbus g_x_wait_obj; /* in xcommon.c */ extern Screen *g_screen; /* in xcommon.c */ extern int g_screen_num; /* in xcommon.c */ -int g_outbound_clipboard_restricted = 0; +extern int g_restrict_outbound_clipboard; /* in chansrv.c */ int g_clip_up = 0; @@ -381,25 +378,6 @@ clipboard_init(void) return 0; } - /* reading config */ - g_cfg = g_new0(struct config_sesman, 1); - - if (0 == g_cfg) - { - g_printf("error creating config: quitting.\n"); - g_deinit(); - g_exit(1); - } - - if (0 != config_read(g_cfg)) - { - log_error("clipboard: error reading config. quitting."); - return 1; - } - - //one-way clipboard - g_outbound_clipboard_restricted = g_cfg->sec.restrict_outbound_clipboard; - xfuse_init(); xcommon_init(); g_incr_max_req_size = XMaxRequestSize(g_display) * 4 - 24; @@ -2521,13 +2499,13 @@ clipboard_xevent(void *xevent) switch (lxevent->type) { case SelectionNotify: - if (g_outbound_clipboard_restricted == 0) + if (g_restrict_outbound_clipboard == 0) { clipboard_event_selection_notify(lxevent); } else { - log_debug("outbound clipboard is restricted because %s is True in config", SESMAN_CFG_RESTRICT_CLIPBOARD); + log_debug("outbound clipboard is restricted because of config"); return 1; } break; diff --git a/sesman/chansrv/config.c b/sesman/chansrv/config.c deleted file mode 100644 index 82a7fbd5..00000000 --- a/sesman/chansrv/config.c +++ /dev/null @@ -1 +0,0 @@ -#include "../config.c" \ No newline at end of file diff --git a/sesman/session.c b/sesman/session.c index 0d9fdc70..b437cfd4 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -374,6 +374,10 @@ session_start_chansrv(char *username, int display) g_cfg->env_names, g_cfg->env_values); + if (g_cfg->sec.restrict_outbound_clipboard == 1) { + g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1); + } + /* executing chansrv */ g_execvp(exe_path, (char **) (chansrv_params->items)); /* should not get here */ From 56fe9613495d6eabd2a170035b44098b961fe3f9 Mon Sep 17 00:00:00 2001 From: Jaroslaw Osmanski Date: Fri, 8 Mar 2019 08:42:18 +0100 Subject: [PATCH 11/23] Fixed style and format issues. --- sesman/chansrv/chansrv.c | 6 ++++-- sesman/config.c | 3 +-- sesman/config.h | 14 +++++++------- sesman/session.c | 3 ++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 3d5ed08f..04a73000 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -1793,8 +1793,10 @@ main(int argc, char **argv) } restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD"); - if (restrict_outbound_clipboard_env != 0) { - if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0) { + if (restrict_outbound_clipboard_env != 0) + { + if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0) + { g_restrict_outbound_clipboard = 1; } } diff --git a/sesman/config.c b/sesman/config.c index a42bb47f..1639517d 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -275,12 +275,11 @@ config_read_security(int file, struct config_security *sc, sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i)); } - if (0 == g_strcasecmp(buf, SESMAN_CFG_RESTRICT_CLIPBOARD)) + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD)) { sc->restrict_outbound_clipboard = g_text2bool((char *)list_get_item(param_v, i)); } - } return 0; diff --git a/sesman/config.h b/sesman/config.h index b8e8bc76..d465687f 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -54,13 +54,13 @@ #define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog" #define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel" */ -#define SESMAN_CFG_SECURITY "Security" -#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry" -#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin" -#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers" -#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins" -#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck" -#define SESMAN_CFG_RESTRICT_CLIPBOARD "RestrictOutboundClipboard" +#define SESMAN_CFG_SECURITY "Security" +#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry" +#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin" +#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers" +#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins" +#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck" +#define SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD "RestrictOutboundClipboard" #define SESMAN_CFG_SESSIONS "Sessions" #define SESMAN_CFG_SESS_MAX "MaxSessions" diff --git a/sesman/session.c b/sesman/session.c index b437cfd4..9fab0392 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -374,7 +374,8 @@ session_start_chansrv(char *username, int display) g_cfg->env_names, g_cfg->env_values); - if (g_cfg->sec.restrict_outbound_clipboard == 1) { + if (g_cfg->sec.restrict_outbound_clipboard == 1) + { g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1); } From 46b4a9b7c8ae555b2dc3e2a1c2ab42717aa315d4 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Wed, 20 Mar 2019 16:55:02 +0900 Subject: [PATCH 12/23] docs: sesman and sesrun now have xrdp- prefix --- docs/man/xrdp-sesman.8.in | 8 ++++---- docs/man/xrdp-sesrun.8.in | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/man/xrdp-sesman.8.in b/docs/man/xrdp-sesman.8.in index 73c8ee42..f475d4d4 100644 --- a/docs/man/xrdp-sesman.8.in +++ b/docs/man/xrdp-sesman.8.in @@ -23,15 +23,15 @@ Kills running \fBxrdp\-sesman\fR daemon. Output help information and exit. .SH "FILES" -@bindir@/sesman +@bindir@/xrdp\-sesman .br -@bindir@/sesrun +@bindir@/xrdp\-sesrun .br @sysconfdir@/xrdp/sesman.ini .br -@localstatedir@/log/sesman.log +@localstatedir@/log/xrdp\-sesman.log .br -@localstatedir@/run/sesman.pid +@localstatedir@/run/xrdp\-sesman.pid .SH "AUTHORS" Jay Sorg diff --git a/docs/man/xrdp-sesrun.8.in b/docs/man/xrdp-sesrun.8.in index 86e9129d..0e06f878 100644 --- a/docs/man/xrdp-sesrun.8.in +++ b/docs/man/xrdp-sesrun.8.in @@ -32,9 +32,9 @@ Screen height Session color depth .SH "FILES" -@bindir@/sesman +@bindir@/xrdp\-sesman .br -@bindir@/sesrun +@bindir@/xrdp\-sesrun .SH "AUTHORS" Jay Sorg From 4f85f8787bf8c1a5fc44079c1a9ee58a51fa4b4f Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Wed, 20 Mar 2019 17:00:17 +0900 Subject: [PATCH 13/23] xrdpwin: xrdp.sourceforge.net -> www.xrdp.org --- xrdp/xrdpwin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index ea93e54a..1544e7c3 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -351,7 +351,7 @@ main(int argc, char **argv) g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln("See http://www.xrdp.org for more information."); g_writeln("%s", ""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); @@ -506,7 +506,7 @@ main(int argc, char **argv) g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln("See http://www.xrdp.org for more information."); g_writeln("%s", ""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); @@ -521,7 +521,7 @@ main(int argc, char **argv) g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); - g_writeln("See http://xrdp.sourceforge.net for more information."); + g_writeln("See http://www.xrdp.org for more information."); g_writeln("Version %s", PACKAGE_VERSION); g_writeln("%s", ""); g_exit(0); From 81703c426f8498022c28a231df7d88ca28bfa842 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 28 Mar 2019 11:42:32 +0900 Subject: [PATCH 14/23] sesman: Fix default_wm and reconnect_sh refer wrong path after SIGHUP Changes in #1147 had a bug. Fixes #1315. Reported by: Daniel Hoffend --- sesman/config.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/sesman/config.c b/sesman/config.c index 1639517d..cce75bf2 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -185,11 +185,11 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n, if (cf->default_wm[0] != '/') { /* sizeof operator returns string length including null terminator */ - length = sizeof(XRDP_CFG_PATH) + g_strlen(g_cfg->default_wm) + 1; /* '/' */ + length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->default_wm) + 1; /* '/' */ buf = (char *)g_malloc(length, 0); - g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); - g_free(g_cfg->default_wm); - g_cfg->default_wm = g_strdup(buf); + g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->default_wm); + g_free(cf->default_wm); + cf->default_wm = g_strdup(buf); g_free(buf); } @@ -206,14 +206,23 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n, if (cf->reconnect_sh[0] != '/') { /* sizeof operator returns string length including null terminator */ - length = sizeof(XRDP_CFG_PATH) + g_strlen(g_cfg->reconnect_sh) + 1; /* '/' */ + length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->reconnect_sh) + 1; /* '/' */ buf = (char *)g_malloc(length, 0); - g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, g_cfg->reconnect_sh); - g_free(g_cfg->reconnect_sh); - g_cfg->reconnect_sh = g_strdup(buf); + g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->reconnect_sh); + g_free(cf->reconnect_sh); + cf->reconnect_sh = g_strdup(buf); g_free(buf); } + log_message(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__); + log_message(LOG_LEVEL_TRACE, " listen_address = %s", cf->listen_address); + log_message(LOG_LEVEL_TRACE, " listen_port = %s", cf->listen_port); + log_message(LOG_LEVEL_TRACE, " enable_user_wm = %d", cf->enable_user_wm); + log_message(LOG_LEVEL_TRACE, " default_wm = %s", cf->default_wm); + log_message(LOG_LEVEL_TRACE, " user_wm = %s", cf->user_wm); + log_message(LOG_LEVEL_TRACE, " reconnect_sh = %s", cf->reconnect_sh); + log_message(LOG_LEVEL_TRACE, " auth_file_path = %s", cf->auth_file_path); + return 0; } From c31b3b0dc2d046b9545442f207ce1b6d406b441a Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Mon, 4 Mar 2019 15:52:49 +0000 Subject: [PATCH 15/23] chansrv_fuse.c tidyups - Remove unused USE_SYNC_FLAG macro - Remove unused members invoke_fuse, off, dirbuf1 from XFUSE_INFO - Clear f_fifo_opendir entries on deinit - Added some comments and fixed some others --- sesman/chansrv/chansrv_fuse.c | 178 ++++++++++++++-------------------- 1 file changed, 71 insertions(+), 107 deletions(-) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 2eb8efda..14b446af 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -37,8 +37,6 @@ * */ -//#define USE_SYNC_FLAG - /* FUSE mount point */ char g_fuse_root_path[256] = ""; char g_fuse_clipboard_path[256] = ""; /* for clipboard use */ @@ -198,16 +196,13 @@ struct xfuse_info fuse_req_t req; fuse_ino_t inode; fuse_ino_t new_inode; - int invoke_fuse; char name[1024]; char new_name[1024]; tui32 device_id; - int reply_type; + int reply_type; /* RT_FUSE_REPLY_xxx */ int mode; int type; size_t size; - off_t off; - struct dirbuf1 dirbuf1; }; typedef struct xfuse_info XFUSE_INFO; @@ -287,11 +282,6 @@ static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode); static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode); static void xfuse_update_xrdpfs_size(void); -#ifdef USE_SYNC_FLAG -static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size, - off_t off, struct fuse_file_info *fi); -#endif - /* forward declarations for FUSE callbacks */ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name); @@ -492,6 +482,14 @@ xfuse_init(void) int xfuse_deinit(void) { + struct opendir_req *odreq; + /* Fail any waiting FUSE requests in the FIFO */ + while (!fifo_is_empty(&g_fifo_opendir)) + { + odreq = (struct opendir_req *)fifo_remove(&g_fifo_opendir); + fuse_reply_err(odreq->req, EBADF); + g_free(odreq); + } fifo_deinit(&g_fifo_opendir); if (g_ch != 0) @@ -1531,6 +1529,8 @@ int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) } /** + * This routine is called by devredir when the opendir_req entry at the + * front of the opendir FIFO has completed processing. *****************************************************************************/ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) @@ -1551,8 +1551,7 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) if (IoStatus != 0) { /* command failed */ - if (fip->invoke_fuse) - fuse_reply_err(fip->req, ENOENT); + fuse_reply_err(fip->req, ENOENT); goto done; } @@ -1560,14 +1559,15 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) if (!xfuse_is_inode_valid(fip->inode)) { log_error("inode %ld is not valid", fip->inode); - if (fip->invoke_fuse) - fuse_reply_err(fip->req, EBADF); + fuse_reply_err(fip->req, EBADF); goto done; } xfuse_delete_stale_entries(fip->inode); - /* this will be used by xfuse_cb_readdir() */ + /* Generate a FUSE reply. + * The dir_info struct will be used by xfuse_cb_readdir() + */ di = g_new0(struct dir_info, 1); di->index = FIRST_INODE; fip->fi->fh = (tintptr) di; @@ -1576,10 +1576,9 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) done: - if (fip) - free(fip); + free(fip); - /* remove current request */ + /* remove completed request */ g_free(fifo_remove(&g_fifo_opendir)); while (1) @@ -1614,9 +1613,6 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, if (IoStatus != 0) { - if (!fip->invoke_fuse) - goto done; - switch (IoStatus) { case 0xC0000022: @@ -1642,8 +1638,7 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, if (fh == NULL) { log_error("system out of memory"); - if (fip->invoke_fuse) - fuse_reply_err(fip->req, ENOMEM); + fuse_reply_err(fip->req, ENOMEM); free(fip); return; @@ -1658,73 +1653,70 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, fip, fip->fi, (long long) fip->fi->fh); } - if (fip->invoke_fuse) + if (fip->reply_type == RT_FUSE_REPLY_OPEN) { - if (fip->reply_type == RT_FUSE_REPLY_OPEN) - { - log_debug("sending fuse_reply_open(); " - "DeviceId=%d FileId=%d req=%p fi=%p", - fh->DeviceId, fh->FileId, fip->req, fip->fi); + log_debug("sending fuse_reply_open(); " + "DeviceId=%d FileId=%d req=%p fi=%p", + fh->DeviceId, fh->FileId, fip->req, fip->fi); - /* update open count */ - if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL) - xinode->nopen++; + /* update open count */ + if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL) + xinode->nopen++; - fuse_reply_open(fip->req, fip->fi); - } - else if (fip->reply_type == RT_FUSE_REPLY_CREATE) - { - struct fuse_entry_param e; + fuse_reply_open(fip->req, fip->fi); + } + else if (fip->reply_type == RT_FUSE_REPLY_CREATE) + { + struct fuse_entry_param e; // LK_TODO #if 0 - if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL) - { - log_error("inode at inode_table[%ld] is NULL", fip->inode); - fuse_reply_err(fip->req, EBADF); - goto done; - } + if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL) + { + log_error("inode at inode_table[%ld] is NULL", fip->inode); + fuse_reply_err(fip->req, EBADF); + goto done; + } #else - /* create entry in xrdp file system */ - xinode = xfuse_create_file_in_xrdp_fs(fip->device_id, fip->inode, - fip->name, fip->mode); - if (xinode == NULL) - { - fuse_reply_err(fip->req, ENOMEM); - return; - } + /* create entry in xrdp file system */ + xinode = xfuse_create_file_in_xrdp_fs(fip->device_id, fip->inode, + fip->name, fip->mode); + if (xinode == NULL) + { + fuse_reply_err(fip->req, ENOMEM); + return; + } #endif - memset(&e, 0, sizeof(struct fuse_entry_param)); + memset(&e, 0, sizeof(struct fuse_entry_param)); - e.ino = xinode->inode; - e.attr_timeout = XFUSE_ATTR_TIMEOUT; - e.entry_timeout = XFUSE_ENTRY_TIMEOUT; - e.attr.st_ino = xinode->inode; - e.attr.st_mode = xinode->mode; - e.attr.st_nlink = xinode->nlink; - e.attr.st_uid = xinode->uid; - e.attr.st_gid = xinode->gid; - e.attr.st_size = xinode->size; - e.attr.st_atime = xinode->atime; - e.attr.st_mtime = xinode->mtime; - e.attr.st_ctime = xinode->ctime; - e.generation = 1; + e.ino = xinode->inode; + e.attr_timeout = XFUSE_ATTR_TIMEOUT; + e.entry_timeout = XFUSE_ENTRY_TIMEOUT; + e.attr.st_ino = xinode->inode; + e.attr.st_mode = xinode->mode; + e.attr.st_nlink = xinode->nlink; + e.attr.st_uid = xinode->uid; + e.attr.st_gid = xinode->gid; + e.attr.st_size = xinode->size; + e.attr.st_atime = xinode->atime; + e.attr.st_mtime = xinode->mtime; + e.attr.st_ctime = xinode->ctime; + e.generation = 1; - if (fip->mode == S_IFDIR) - { - fuse_reply_entry(fip->req, &e); - } - else - { - xinode->nopen++; - fuse_reply_create(fip->req, &e, fip->fi); - } + if (fip->mode == S_IFDIR) + { + fuse_reply_entry(fip->req, &e); } else { - log_error("invalid reply type: %d", fip->reply_type); + xinode->nopen++; + fuse_reply_create(fip->req, &e, fip->fi); } } + else + { + log_error("invalid reply type: %d", fip->reply_type); + } done: @@ -1970,7 +1962,6 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) fuse_reply_entry(req, &e); log_debug("found entry for parent=%ld name=%s uid=%d gid=%d", parent, name, xinode->uid, xinode->gid); - return; } /** @@ -2265,7 +2256,6 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent, fip->req = req; fip->inode = parent; - fip->invoke_fuse = 1; fip->device_id = device_id; strncpy(fip->name, name, 1024); fip->name[1023] = 0; @@ -2287,7 +2277,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent, { if (devredir_rmdir_or_file((void *) fip, device_id, cptr, O_RDWR)) { - log_error("failed to send dev_redir_get_dir_listing() cmd"); + log_error("failed to send devredir_rmdir_or_file() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); return; @@ -2400,7 +2390,6 @@ static void xfuse_cb_rename(fuse_req_t req, strncpy(fip->new_name, new_name, 1024); fip->name[1023] = 0; fip->new_name[1023] = 0; - fip->invoke_fuse = 1; fip->device_id = device_id; if ((cp = strchr(new_full_path, '/')) == NULL) @@ -2501,7 +2490,6 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, fip->req = req; fip->fi = fi; fip->inode = parent; - fip->invoke_fuse = 1; fip->device_id = device_id; fip->mode = type; fip->reply_type = RT_FUSE_REPLY_CREATE; @@ -2528,7 +2516,7 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, if (dev_redir_file_open((void *) fip, device_id, cptr, O_CREAT, type, NULL)) { - log_error("failed to send dev_redir_get_dir_listing() cmd"); + log_error("failed to send dev_redir_file_open() cmd"); fuse_reply_err(req, EREMOTEIO); } } @@ -2595,7 +2583,6 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, fip->req = req; fip->inode = ino; - fip->invoke_fuse = 1; fip->device_id = device_id; fip->fi = fi; @@ -2621,7 +2608,7 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, if (dev_redir_file_open((void *) fip, device_id, cptr, fi->flags, S_IFREG, NULL)) { - log_error("failed to send dev_redir_get_dir_listing() cmd"); + log_error("failed to send dev_redir_file_open() cmd"); fuse_reply_err(req, EREMOTEIO); } } @@ -2679,7 +2666,6 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct fip->req = req; fip->inode = ino; - fip->invoke_fuse = 1; fip->device_id = handle->DeviceId; fip->fi = fi; @@ -2766,7 +2752,6 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size, } fusep->req = req; fusep->inode = ino; - fusep->invoke_fuse = 1; fusep->device_id = fh->DeviceId; fusep->fi = fi; @@ -2815,7 +2800,6 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf, fusep->req = req; fusep->inode = ino; - fusep->invoke_fuse = 1; fusep->device_id = fh->DeviceId; fusep->fi = fi; @@ -3006,22 +2990,6 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino, goto done; /* enumerate resources on a remote device */ - -#ifdef USE_SYNC_FLAG - if (xinode->is_synced) - { - xfuse_enum_dir(req, ino, size, off, fi); - g_free(fifo_remove(&g_fifo_opendir)); - return -1; - } - else - { - goto do_remote_lookup; - } - -do_remote_lookup: -#endif - xfuse_mark_as_stale(ino); log_debug("did not find entry; redirecting call to dev_redir"); @@ -3041,12 +3009,8 @@ do_remote_lookup: fip->req = req; fip->inode = ino; fip->size = 0; - fip->off = 0; fip->fi = fi; - fip->dirbuf1.first_time = 1; - fip->dirbuf1.bytes_in_buf = 0; - fip->invoke_fuse = 1; fip->device_id = device_id; /* we want path minus 'root node of the share' */ From c43c9cd551ecafc3b86fc2092071e24edfd9b720 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Tue, 12 Mar 2019 12:16:50 +0000 Subject: [PATCH 16/23] Code tidyups - Remove unused 'is_synced' member from struct xrdp_inode - Move prototype for xfuse_devredir_cb_write_file() to correct file - Add const correctness to dev_redir_strings_ends_with() function - Add const correctness to fuse_reverse_pathname() function - Moved devredir_proc_cid_* functions out of devredir.h and made static - Added XFUSE_DUMP_ADDED_ENTRIES maro for debugging - Removed duplicate code path in xfuse_remove_dir_or_file() - Removed duplicate code path in xfuse_cb_rename() - Removed duplicate code path in xfuse_create_dir_or_file() - Removed duplicate code path in xfuse_cb_open() - Removed duplicate code path in xfuse_proc_opendir_req() --- sesman/chansrv/chansrv_fuse.c | 180 +++++++++++++++------------------- sesman/chansrv/chansrv_fuse.h | 3 +- sesman/chansrv/devredir.c | 22 +++-- sesman/chansrv/devredir.h | 7 +- 4 files changed, 97 insertions(+), 115 deletions(-) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 14b446af..be7bb7c9 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -128,6 +128,9 @@ void xfuse_devredir_cb_file_close(void *vp) {} #define LOG_DEBUG 2 #define LOG_LEVEL LOG_ERROR +/* Uncomment for detail of added entries */ +#define XFUSE_DUMP_ADDED_ENTRIES + #define log_error(_params...) \ { \ g_write("[%10.10u]: FUSE %s: %d : ERROR: ", \ @@ -267,7 +270,7 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent, static void xfuse_dump_fs(void); static tui32 xfuse_get_device_id_for_inode(fuse_ino_t ino, char *full_path); -static void fuse_reverse_pathname(char *full_path, char *reverse_path); +static void fuse_reverse_pathname(char *full_path, const char *reverse_path); static struct xrdp_inode * xfuse_get_inode_from_pinode_name(fuse_ino_t pinode, const char *name); @@ -1099,9 +1102,9 @@ static void xfuse_dump_fs(void) if ((xinode = g_xrdp_fs.inode_table[i]) == NULL) continue; - log_debug("pinode=%d inode=%d nentries=%d nopen=%d is_synced=%d name=%s", + log_debug("pinode=%d inode=%d nentries=%d nopen=%d name=%s", xinode->parent_inode, xinode->inode, - xinode->nentries, xinode->nopen, xinode->is_synced, + xinode->nentries, xinode->nopen, xinode->name); } log_debug("%s", ""); @@ -1113,10 +1116,10 @@ static void xfuse_dump_fs(void) * @param xino xinode structure to dump *****************************************************************************/ -#if 0 +#ifdef XFUSE_DUMP_ADDED_ENTRIES static void xfuse_dump_xrdp_inode(struct xrdp_inode *xino) { - log_debug("--- dumping struct xinode ---"); + log_debug("--- dumping struct xinode %p ---",xino); log_debug("name: %s", xino->name); log_debug("parent_inode: %d", xino->parent_inode); log_debug("inode: %d", xino->inode); @@ -1191,19 +1194,35 @@ static tui32 xfuse_get_device_id_for_inode(fuse_ino_t ino, char *full_path) * @param reverse_path path name in the reverse order *****************************************************************************/ -static void fuse_reverse_pathname(char *full_path, char *reverse_path) +static void fuse_reverse_pathname(char *full_path, const char *reverse_path) { - char *cptr; + char *optr; /* Output pointer */ + const char *start;/* Pointer to start of current element in input */ + const char *end; /* Ditto for the end */ - full_path[0] = 0; + /* Start writing the result from the end */ + optr = full_path + strlen(reverse_path); + *optr = '\0'; - while ((cptr = strrchr(reverse_path, '/')) != NULL) + start = reverse_path; + while ((end = strchr(start, '/')) != NULL) { - strcat(full_path, cptr + 1); - strcat(full_path, "/"); - cptr[0] = 0; + /* Copy current element to the end of the result... */ + optr -= (end - start); + memcpy(optr, start, (end - start)); + /* And precede with a '/' */ + *--optr = '/'; + + /* Next element starts after the '/' */ + start = end + 1; } - strcat(full_path, reverse_path); + + /* Last bit (if reverse_path doesn't end with a '/') */ + if (optr != full_path) + { + memcpy(full_path, start, optr - full_path); + } + } /** @@ -1278,7 +1297,6 @@ xfuse_create_file_in_xrdp_fs(tui32 device_id, int pinode, const char *name, xinode->mtime = cur_time; xinode->ctime = cur_time; xinode->device_id = device_id; - xinode->is_synced = 1; strcpy(xinode->name, name); if (type == S_IFDIR) @@ -1294,6 +1312,9 @@ xfuse_create_file_in_xrdp_fs(tui32 device_id, int pinode, const char *name, g_xrdp_fs.inode_table[xinode->inode] = xinode; g_xrdp_fs.num_entries++; +#ifdef XFUSE_DUMP_ADDED_ENTRIES + xfuse_dump_xrdp_inode(xinode); +#endif /* bump up lookup count in parent dir */ xinodep = g_xrdp_fs.inode_table[pinode]; @@ -1525,6 +1546,9 @@ int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) xfuse_update_xrdpfs_size(); xfuse_dump_fs(); +#ifdef XFUSE_DUMP_ADDED_ENTRIES + xfuse_dump_xrdp_inode(xinode); +#endif return 0; } @@ -1853,7 +1877,6 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) if (fip->inode != fip->new_inode) { /* file has been moved to a different dir */ - old_xinode->is_synced = 1; g_xrdp_fs.inode_table[fip->inode]->nentries--; g_xrdp_fs.inode_table[fip->new_inode]->nentries++; } @@ -2097,8 +2120,6 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, if (xinode->parent_inode != ino) continue; - xinode->is_synced = 1; - if (first_time) { first_time = 0; @@ -2189,7 +2210,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent, { XFUSE_INFO *fip; XRDP_INODE *xinode; - char *cptr; + const char *cptr; char full_path[4096]; tui32 device_id; @@ -2264,24 +2285,15 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent, /* we want path minus 'root node of the share' */ if ((cptr = strchr(full_path, '/')) == NULL) { - /* get dev_redir to open the remote file */ - if (devredir_rmdir_or_file((void *) fip, device_id, "\\", O_RDWR)) - { - log_error("failed to send dev_redir_open_file() cmd"); - fuse_reply_err(req, EREMOTEIO); - free(fip); - return; - } + cptr = "\\"; } - else + + /* get dev_redir to open the remote file */ + if (devredir_rmdir_or_file((void *) fip, device_id, cptr, O_RDWR)) { - if (devredir_rmdir_or_file((void *) fip, device_id, cptr, O_RDWR)) - { - log_error("failed to send devredir_rmdir_or_file() cmd"); - fuse_reply_err(req, EREMOTEIO); - free(fip); - return; - } + log_error("failed to send devredir_rmdir_or_file() cmd"); + fuse_reply_err(req, EREMOTEIO); + free(fip); } } @@ -2292,7 +2304,7 @@ static void xfuse_cb_rename(fuse_req_t req, XRDP_INODE *old_xinode; XFUSE_INFO *fip; tui32 new_device_id; - char *cptr; + const char *cptr; char old_full_path[1024]; char new_full_path[1024]; const char *cp; @@ -2392,32 +2404,24 @@ static void xfuse_cb_rename(fuse_req_t req, fip->new_name[1023] = 0; fip->device_id = device_id; - if ((cp = strchr(new_full_path, '/')) == NULL) - cp = "\\"; - /* we want path minus 'root node of the share' */ if ((cptr = strchr(old_full_path, '/')) == NULL) { - /* get dev_redir to open the remote file */ - if (dev_redir_file_open((void *) fip, device_id, "\\", - O_RDWR, S_IFREG | OP_RENAME_FILE, cp)) - { - log_error("failed to send dev_redir_file_open() cmd"); - fuse_reply_err(req, EREMOTEIO); - free(fip); - return; - } + cptr = "\\"; } - else + + if ((cp = strchr(new_full_path, '/')) == NULL) { - if (dev_redir_file_open((void *) fip, device_id, cptr, - O_RDWR, S_IFREG | OP_RENAME_FILE, cp)) - { - log_error("failed to send dev_redir_file_open() cmd"); - fuse_reply_err(req, EREMOTEIO); - free(fip); - return; - } + cp = "\\"; + } + + /* get dev_redir to open the remote file */ + if (dev_redir_file_open((void *) fip, device_id, cptr, + O_RDWR, S_IFREG | OP_RENAME_FILE, cp)) + { + log_error("failed to send dev_redir_file_open() cmd"); + fuse_reply_err(req, EREMOTEIO); + free(fip); } } @@ -2437,7 +2441,7 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, struct fuse_file_info *fi, int type) { XFUSE_INFO *fip; - char *cptr; + const char *cptr; char full_path[1024]; tui32 device_id; @@ -2503,22 +2507,15 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, /* we want path minus 'root node of the share' */ if ((cptr = strchr(full_path, '/')) == NULL) { - /* get dev_redir to open the remote file */ - if (dev_redir_file_open((void *) fip, device_id, "\\", - O_CREAT, type, NULL)) - { - log_error("failed to send dev_redir_open_file() cmd"); - fuse_reply_err(req, EREMOTEIO); - } + cptr = "\\"; } - else + + /* get dev_redir to open the remote file */ + if (dev_redir_file_open((void *) fip, device_id, cptr, + O_CREAT, type, NULL)) { - if (dev_redir_file_open((void *) fip, device_id, cptr, - O_CREAT, type, NULL)) - { - log_error("failed to send dev_redir_file_open() cmd"); - fuse_reply_err(req, EREMOTEIO); - } + log_error("failed to send dev_redir_file_open() cmd"); + fuse_reply_err(req, EREMOTEIO); } } @@ -2531,7 +2528,7 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, { XRDP_INODE *xinode; XFUSE_INFO *fip; - char *cptr; + const char *cptr; char full_path[4096]; tui32 device_id; @@ -2595,22 +2592,14 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, /* we want path minus 'root node of the share' */ if ((cptr = strchr(full_path, '/')) == NULL) { - /* get dev_redir to open the remote file */ - if (dev_redir_file_open((void *) fip, device_id, "\\", - fi->flags, S_IFREG, NULL)) - { - log_error("failed to send dev_redir_open_file() cmd"); - fuse_reply_err(req, EREMOTEIO); - } + cptr = "\\"; } - else + /* get dev_redir to open the remote file */ + if (dev_redir_file_open((void *) fip, device_id, cptr, + fi->flags, S_IFREG, NULL)) { - if (dev_redir_file_open((void *) fip, device_id, cptr, - fi->flags, S_IFREG, NULL)) - { - log_error("failed to send dev_redir_file_open() cmd"); - fuse_reply_err(req, EREMOTEIO); - } + log_error("failed to send dev_redir_file_open() cmd"); + fuse_reply_err(req, EREMOTEIO); } } @@ -2963,7 +2952,7 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino, XFUSE_INFO *fip; tui32 device_id; char full_path[4096]; - char *cptr; + const char *cptr; log_debug("inode=%ld", ino); @@ -3016,20 +3005,13 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino, /* we want path minus 'root node of the share' */ if ((cptr = strchr(full_path, '/')) == NULL) { - /* enumerate root dir */ - if (dev_redir_get_dir_listing((void *) fip, device_id, "\\")) - { - log_error("failed to send dev_redir_get_dir_listing() cmd"); - fuse_reply_buf(req, NULL, 0); - } + cptr = "\\"; } - else + + if (dev_redir_get_dir_listing((void *) fip, device_id, cptr)) { - if (dev_redir_get_dir_listing((void *) fip, device_id, cptr)) - { - log_error("failed to send dev_redir_get_dir_listing() cmd"); - fuse_reply_buf(req, NULL, 0); - } + log_error("failed to send dev_redir_get_dir_listing() cmd"); + fuse_reply_buf(req, NULL, 0); } return 0; diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 7834898f..7183c038 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -36,8 +36,6 @@ struct xrdp_inode time_t ctime; /* Time of last status change. */ char name[1024]; /* Dir or filename */ tui32 device_id; /* for file system redirection */ - char is_synced; /* dir struct has been read from */ - /* remote device, done just once */ int lindex; /* used in clipboard operations */ int is_loc_resource; /* this is not a redirected resource */ int close_in_progress; /* close cmd sent to client */ @@ -60,6 +58,7 @@ int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int linde int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode); void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus); void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId); +void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length); void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length); void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus); void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus); diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index 629b3cc9..03fcfc68 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -106,7 +106,13 @@ tui32 g_device_id; /* unique device ID - announced by client */ tui16 g_client_rdp_version; /* returned by client */ struct stream *g_input_stream = NULL; -void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length); +/* + * Local functions called from dev_redir_proc_device_iocompletion() + */ +static void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus); +static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus); +static void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus); +static void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus); /*****************************************************************************/ int @@ -1514,12 +1520,12 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len) } int -dev_redir_string_ends_with(char *string, char c) +dev_redir_string_ends_with(const char *string, char c) { - int len; + size_t len; len = strlen(string); - return (string[len - 1] == c) ? 1 : 0; + return (len > 0 && string[len - 1] == c) ? 1 : 0; } void @@ -1530,7 +1536,7 @@ devredir_insert_RDPDR_header(struct stream *s, tui16 Component, xstream_wr_u16_le(s, PacketId); } -void +static void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus) { struct stream *s; @@ -1567,7 +1573,7 @@ devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus) return; } -void +static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus) { FUSE_DATA *fuse_data; @@ -1594,7 +1600,7 @@ devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus) IRP_MJ_CLOSE, 0, 32); } -void +static void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) { struct stream *s; @@ -1647,7 +1653,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) return; } -void +static void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus) { FUSE_DATA *fuse_data; diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h index 5618b39c..558975ff 100644 --- a/sesman/chansrv/devredir.h +++ b/sesman/chansrv/devredir.h @@ -84,16 +84,11 @@ void devredir_insert_DeviceIoRequest(struct stream *s, void devredir_cvt_slash(char *path); void devredir_cvt_to_unicode(char *unicode, const char *path); void devredir_cvt_from_unicode_len(char *path, char *unicode, int len); -int dev_redir_string_ends_with(char *string, char c); +int dev_redir_string_ends_with(const char *string, char c); void devredir_insert_RDPDR_header(struct stream *s, tui16 Component, tui16 PacketId); -void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus); -void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus); -void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus); -void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus); - /* called from FUSE module */ int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path); From ef9013b4d9923819917de89b0f2f621281efce23 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Wed, 13 Mar 2019 10:56:37 +0000 Subject: [PATCH 17/23] Implement O_WRONLY option for open file Allows files to be overwritten on Linux without EIO Logging improved on failed write --- sesman/chansrv/chansrv_fuse.c | 71 ++++++++++++++++++++++++++--------- sesman/chansrv/chansrv_fuse.h | 6 ++- sesman/chansrv/devredir.c | 37 +++++++++++++----- sesman/chansrv/devredir.h | 3 ++ 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index be7bb7c9..6256ccf9 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -72,7 +72,7 @@ int xfuse_file_contents_size(int stream_id, int file_size) { r int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex) { return 0; } int xfuse_create_share(tui32 device_id, const char *dirname) { return 0; } void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {} -void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length) {} +void xfuse_devredir_cb_write_file(void *vp, tui32 IoStatus, const char *buf, size_t length) {} void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length) {} int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) { return 0; } void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {} @@ -1639,12 +1639,12 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, { switch (IoStatus) { - case 0xC0000022: + case NT_STATUS_ACCESS_DENIED: fuse_reply_err(fip->req, EACCES); break; - case 0xC0000033: - case 0xC0000034: + case NT_STATUS_OBJECT_NAME_INVALID: + case NT_STATUS_OBJECT_NAME_NOT_FOUND: fuse_reply_err(fip->req, ENOENT); break; @@ -1762,7 +1762,10 @@ void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length) free(fip); } -void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length) +void xfuse_devredir_cb_write_file(void *vp, + tui32 IoStatus, + const char *buf, + size_t length) { XRDP_INODE *xinode; XFUSE_INFO *fip; @@ -1771,20 +1774,34 @@ void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length) if ((fip == NULL) || (fip->req == NULL) || (fip->fi == NULL)) { log_error("fip, fip->req or fip->fi is NULL"); - return; } - - log_debug("+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx", - fip, fip->fi, (long long) fip->fi->fh); - - fuse_reply_write(fip->req, length); - - /* update file size */ - if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL) - xinode->size += length; else - log_error("inode at inode_table[%ld] is NULL", fip->inode); + { + log_debug( + "+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx", + fip, fip->fi, (long long) fip->fi->fh); + if (IoStatus != NT_STATUS_SUCCESS) + { + log_error("Write NTSTATUS is %d", (int) IoStatus); + fuse_reply_err(fip->req, EIO); + } + else + { + fuse_reply_write(fip->req, length); + + /* update file size */ + if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL) + { + xinode->size += length; + } + else + { + log_error("inode at inode_table[%ld] is NULL", fip->inode); + } + + } + } free(fip); } @@ -2551,11 +2568,24 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, } if (xinode->mode & S_IFDIR) { - log_debug("reading a dir not allowed!"); + log_debug("reading/writing a dir not allowed!"); fuse_reply_err(req, EISDIR); return; } + switch (fi->flags & O_ACCMODE) + { + case O_RDONLY: + case O_WRONLY: + case O_RDWR: + break; + + default: + log_debug("Invalid access mode specified"); + fuse_reply_err(req, EINVAL); + return; + } + device_id = xfuse_get_device_id_for_inode(ino, full_path); if (xinode->is_loc_resource) @@ -2594,7 +2624,12 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, { cptr = "\\"; } - /* get dev_redir to open the remote file */ + /* get dev_redir to open the remote file + * + * For a successful call, if the caller has set O_TRUNC when writing + * the file, fuse should call us back via fuse_cb_setattr() to set + * the size to zero - we don't need to do this ourselves. + */ if (dev_redir_file_open((void *) fip, device_id, cptr, fi->flags, S_IFREG, NULL)) { diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 7183c038..945a4bef 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -58,7 +58,11 @@ int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int linde int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode); void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus); void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId); -void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length); +void xfuse_devredir_cb_write_file( + void *vp, + tui32 IoStatus, + const char *buf, + size_t length); void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length); void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus); void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus); diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index 03fcfc68..e2a29394 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -822,7 +822,8 @@ dev_redir_proc_device_iocompletion(struct stream *s) } else { - xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length); + xfuse_devredir_cb_write_file(fuse_data->data_ptr, IoStatus, + s->p, Length); devredir_irp_delete(irp); } break; @@ -1107,14 +1108,30 @@ dev_redir_file_open(void *fusep, tui32 device_id, const char *path, } else { - log_debug("open file in O_RDWR"); #if 1 - /* without the 0x00000010 rdesktop opens files in */ - /* O_RDONLY instead of O_RDWR mode */ - if (mode & O_RDWR) - DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | DA_SYNCHRONIZE | 0x00000010; - else - DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE; + switch(mode & O_ACCMODE) + { + case O_RDONLY: + log_debug("open file in O_RDONLY"); + DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE; + break; + + case O_WRONLY: + log_debug("open file in O_WRONLY"); + DesiredAccess = DA_FILE_WRITE_DATA | DA_SYNCHRONIZE; + break; + + default: + /* + * The access mode could conceivably be invalid here, + * but we assume this has been checked by the caller + */ + log_debug("open file in O_RDWR"); + /* without the 0x00000010 rdesktop opens files in */ + /* O_RDONLY instead of O_RDWR mode */ + DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | + DA_SYNCHRONIZE | 0x00000010; + } CreateOptions = CO_FILE_SYNCHRONOUS_IO_NONALERT; CreateDisposition = CD_FILE_OPEN; // WAS 1 @@ -1283,7 +1300,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId, if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { log_error("no IRP found with FileId = %d", FileId); - xfuse_devredir_cb_write_file(fusep, NULL, 0); + xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, NULL, 0); xstream_free(s); return -1; } @@ -1292,7 +1309,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId, if ((new_irp = devredir_irp_clone(irp)) == NULL) { /* system out of memory */ - xfuse_devredir_cb_write_file(fusep, NULL, 0); + xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, NULL, 0); xstream_free(s); return -1; } diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h index 558975ff..00ed5dda 100644 --- a/sesman/chansrv/devredir.h +++ b/sesman/chansrv/devredir.h @@ -260,6 +260,9 @@ enum CREATE_OPTIONS #define NT_STATUS_SUCCESS 0x00000000 #define NT_STATUS_UNSUCCESSFUL 0xC0000001 +#define NT_STATUS_ACCESS_DENIED 0xC0000022 +#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000033 +#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034 /* * File system ioctl codes From d154df5059cdfc2ac1eb34025e5bf8c07b962f1a Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 21 Mar 2019 16:48:01 +0000 Subject: [PATCH 18/23] Add remote drive lookup functionality to fuse - Replace xfuse_cb_enum_dir() directory callback for adding files with more general xfuse_devredir_add_file_or_dir() to be called from a directory or a lookup operation. - Moved XRDP_INODE out of public interface for chansrv_fuse, and replaced with simpler struct file_attr to pass to xfuse_devredir_add_file_or_dir() - Allow a struct file_attr to be placed in an IRP for assembly of file attributes over multiple IRP_MJ_QUERY_INFORMATION requats. - Add dev_redir_lookup_entry() to public interface for devredir.c - Add xfuse_devredir_cb_lookup_entry() callback to public interface for chansrv-fuse.c --- sesman/chansrv/chansrv_fuse.c | 305 ++++++++++++++++++++++++------- sesman/chansrv/chansrv_fuse.h | 36 ++-- sesman/chansrv/devredir.c | 333 ++++++++++++++++++++++++++++++++-- sesman/chansrv/devredir.h | 12 +- sesman/chansrv/irp.h | 8 +- 5 files changed, 587 insertions(+), 107 deletions(-) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 6256ccf9..3e8bcab5 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -24,7 +24,6 @@ * this is in func xfuse_check_wait_objs() * o if fuse mount point is already mounted, I get segfault * o in open, check for modes such as O_TRUNC, O_APPEND - * o copying over an existing file does not work * o after a dir is created, the device cannot be unmounted on the client side * so something is holding it up * o in thunar, when I move a file by dragging to another folder, the file @@ -33,7 +32,6 @@ * o fuse ops to support * o touch does not work * o chmod must work - * o cat >> file is not working * */ @@ -74,7 +72,10 @@ int xfuse_create_share(tui32 device_id, const char *dirname) void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {} void xfuse_devredir_cb_write_file(void *vp, tui32 IoStatus, const char *buf, size_t length) {} void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length) {} -int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) { return 0; } +struct xrdp_inode *xfuse_devredir_add_file_or_dir( + void *vp, + const struct file_attr *fattr) + { return NULL;} void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {} void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {} void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {} @@ -129,7 +130,7 @@ void xfuse_devredir_cb_file_close(void *vp) {} #define LOG_LEVEL LOG_ERROR /* Uncomment for detail of added entries */ -#define XFUSE_DUMP_ADDED_ENTRIES +/* #define XFUSE_DUMP_ADDED_ENTRIES */ #define log_error(_params...) \ { \ @@ -167,6 +168,30 @@ void xfuse_devredir_cb_file_close(void *vp) {} #define OP_RENAME_FILE 0x01 +/* a file or dir entry in the xrdp file system */ +struct xrdp_inode +{ + tui32 parent_inode; /* Parent serial number. */ + tui32 inode; /* File serial number. */ + tui32 mode; /* File mode. */ + tui32 nlink; /* symbolic link count. */ + tui32 nentries; /* number of entries in a dir */ + tui32 nopen; /* number of simultaneous opens */ + tui32 uid; /* User ID of the file's owner. */ + tui32 gid; /* Group ID of the file's group. */ + size_t size; /* Size of file, in bytes. */ + time_t atime; /* Time of last access. */ + time_t mtime; /* Time of last modification. */ + time_t ctime; /* Time of last status change. */ + char name[1024]; /* Dir or filename */ + tui32 device_id; /* for file system redirection */ + int lindex; /* used in clipboard operations */ + int is_loc_resource; /* this is not a redirected resource */ + int close_in_progress; /* close cmd sent to client */ + int stale; /* mark file as stale, ok to remove */ +}; +typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode + /* the xrdp file system in memory */ struct xrdp_fs { @@ -356,6 +381,7 @@ static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino, /* misc calls */ static void xfuse_mark_as_stale(fuse_ino_t pinode); static void xfuse_delete_stale_entries(fuse_ino_t pinode); +static void make_fuse_entry_reply(fuse_req_t req, const XRDP_INODE *xinode); /*****************************************************************************/ int @@ -1492,64 +1518,111 @@ static void xfuse_update_xrdpfs_size(void) /** * Add a file or directory to xrdp file system + * + * If the file or directory already exists, its attributes are updated. + * + * Returns a pointer to the xinode if the object was added or updated *****************************************************************************/ -int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) +struct xrdp_inode *xfuse_devredir_add_file_or_dir( + void *vp, + const struct file_attr *fattr) { XFUSE_INFO *fip = (XFUSE_INFO *) vp; - XRDP_INODE *xip = NULL; + XRDP_INODE *xinode = NULL; - if ((fip == NULL) || (xinode == NULL)) + if (fip == NULL) { - log_error("fip or xinode are NULL"); - return -1; + log_error("fip is NULL"); } - - if (!xfuse_is_inode_valid(fip->inode)) + else if (!xfuse_is_inode_valid(fip->inode)) { log_error("inode %ld is not valid", fip->inode); - g_free(xinode); - return -1; } - - log_debug("parent_inode=%ld name=%s", fip->inode, xinode->name); - - /* if filename is . or .. don't add it */ - if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0)) + else if ((strcmp(fattr->name, ".") == 0) || + (strcmp(fattr->name, "..") == 0)) { - g_free(xinode); - return -1; + ; /* filename is . or .. - don't add it */ } - - xfuse_dump_fs(); - - if ((xip = xfuse_get_inode_from_pinode_name(fip->inode, xinode->name)) != NULL) + else { - log_debug("inode=%ld name=%s already exists in xrdp_fs; not adding it", - fip->inode, xinode->name); - g_free(xinode); - xip->stale = 0; - return -1; - } + log_debug("parent_inode=%ld name=%s", fip->inode, fattr->name); + xfuse_dump_fs(); - xinode->parent_inode = fip->inode; - xinode->inode = g_xrdp_fs.next_node++; - xinode->uid = getuid(); - xinode->gid = getgid(); - xinode->device_id = fip->device_id; + /* Does the file already exist ? */ + xinode = xfuse_get_inode_from_pinode_name(fip->inode, fattr->name); + if (xinode != NULL) + { + /* Is the existing file the same type ? */ + if ((xinode->mode & (S_IFREG | S_IFDIR)) == + (fattr->mode & (S_IFREG | S_IFDIR))) + { + log_debug("inode=%ld name=%s already exists in xrdp_fs" + " - updating attributes", + fip->inode, xinode->name); + xinode->mode = fattr->mode; + xinode->size = fattr->size; + xinode->atime = fattr->atime; + xinode->mtime = fattr->mtime; + xinode->ctime = fattr->ctime; + xinode->stale = 0; + } + else + { + /* File type has changed */ + log_debug("inode=%ld name=%s of different type in xrdp_fs" + " - removing", + fip->inode, xinode->name); + if (xinode->mode & S_IFREG) + { + xfuse_delete_file_with_xinode(xinode); + } + else + { + xfuse_delete_dir_with_xinode(xinode); + } + xinode = NULL; + } + } - g_xrdp_fs.num_entries++; + if (xinode == NULL) + { + /* Add a new node to the file system */ + xinode = g_new0(struct xrdp_inode, 1); + if (xinode == NULL) + { + log_debug("g_new0() failed"); + } + else + { + strcpy(xinode->name, fattr->name); + xinode->mode = fattr->mode; + xinode->size = fattr->size; + xinode->atime = fattr->atime; + xinode->mtime = fattr->mtime; + xinode->ctime = fattr->ctime; - /* insert it in xrdp fs and update lookup count */ - g_xrdp_fs.inode_table[xinode->inode] = xinode; - g_xrdp_fs.inode_table[fip->inode]->nentries++; - xfuse_update_xrdpfs_size(); + xinode->parent_inode = fip->inode; + xinode->inode = g_xrdp_fs.next_node++; + xinode->uid = getuid(); + xinode->gid = getgid(); + xinode->device_id = fip->device_id; - xfuse_dump_fs(); + g_xrdp_fs.num_entries++; + + /* insert it in xrdp fs and update lookup count */ + g_xrdp_fs.inode_table[xinode->inode] = xinode; + g_xrdp_fs.inode_table[fip->inode]->nentries++; + xfuse_update_xrdpfs_size(); + + xfuse_dump_fs(); #ifdef XFUSE_DUMP_ADDED_ENTRIES - xfuse_dump_xrdp_inode(xinode); + xfuse_dump_xrdp_inode(xinode); #endif - return 0; + } + } + } + return xinode; } /** @@ -1619,6 +1692,44 @@ done: } } +/** + * This routine is caused as a result of a devredir remote lookup + * instigated by xfuse_cb_lookup() + * + * If the IoStatus is good but there's no xinode, something has gone wrong + * in the devredir layer (no memory, unrecognised reply) + *****************************************************************************/ +void xfuse_devredir_cb_lookup_entry(void *vp, tui32 IoStatus, struct xrdp_inode *xinode) +{ + XFUSE_INFO *fip = (XFUSE_INFO *) vp; + + if (IoStatus == NT_STATUS_SUCCESS) + { + if (xinode != NULL) + { + make_fuse_entry_reply(fip->req, xinode); + } + else + { + fuse_reply_err(fip->req, EIO); + } + } + else + { + switch (IoStatus) + { + case NT_STATUS_NO_SUCH_FILE: + fuse_reply_err(fip->req, ENOENT); + break; + + default: + log_info("Error code %08x - fallthrough", (int) IoStatus); + fuse_reply_err(fip->req, EIO); + break; + } + } +} + void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) { @@ -1791,6 +1902,8 @@ void xfuse_devredir_cb_write_file(void *vp, fuse_reply_write(fip->req, length); /* update file size */ + /* ??? This needs to take into account the offset sent with + * the original request */ if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL) { xinode->size += length; @@ -1959,12 +2072,20 @@ void xfuse_devredir_cb_file_close(void *vp) /** * Look up a directory entry by name and get its attributes * + * If the file can't be found, and it resides on a remote share, devredir + * is asked to look it up. This will result in the following + * callbacks:- + * - xfuse_devredir_add_file_or_dir() (only if the file is found) + * - xfuse_devredir_cb_lookup_entry() to return status to the caller *****************************************************************************/ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { - XRDP_INODE *xinode; - struct fuse_entry_param e; + XFUSE_INFO *fip; + XRDP_INODE *xinode; + char full_path[4096]; + tui32 device_id; + const char *cptr; log_debug("looking for parent=%ld name=%s", parent, name); xfuse_dump_fs(); @@ -1976,32 +2097,60 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) return; } - xinode = xfuse_get_inode_from_pinode_name(parent, name); - if (xinode == NULL) + if (parent == 1 || + g_xrdp_fs.inode_table[parent]->is_loc_resource) { - log_debug("did not find entry for parent=%ld name=%s", parent, name); - fuse_reply_err(req, ENOENT); - return; + /* File cannot be remote - we either know about it or we don't */ + xinode = xfuse_get_inode_from_pinode_name(parent, name); + if (xinode != NULL) + { + log_debug("found entry for parent=%ld name=%s uid=%d gid=%d", + parent, name, xinode->uid, xinode->gid); + make_fuse_entry_reply(req, xinode); + } + else + { + fuse_reply_err(req, ENOENT); + } } + else + { + /* + * specified file resides on redirected share. + * + * We always look these up, as fuse caches stuff for us anyway, and + * it's pointless caching it twice + */ + fip = g_new0(XFUSE_INFO, 1); + if (fip == NULL) + { + log_error("system out of memory"); + fuse_reply_err(req, ENOMEM); + } + else + { + device_id = xfuse_get_device_id_for_inode(parent, full_path); - memset(&e, 0, sizeof(e)); - e.ino = xinode->inode; - e.attr_timeout = XFUSE_ATTR_TIMEOUT; - e.entry_timeout = XFUSE_ENTRY_TIMEOUT; - e.attr.st_ino = xinode->inode; - e.attr.st_mode = xinode->mode; - e.attr.st_nlink = xinode->nlink; - e.attr.st_uid = xinode->uid; - e.attr.st_gid = xinode->gid; - e.attr.st_size = xinode->size; - e.attr.st_atime = xinode->atime; - e.attr.st_mtime = xinode->mtime; - e.attr.st_ctime = xinode->ctime; - e.generation = 1; + /* we want path minus 'root node of the share' */ + if ((cptr = strchr(full_path, '/')) == NULL) + { + cptr = "\\"; + } - fuse_reply_entry(req, &e); - log_debug("found entry for parent=%ld name=%s uid=%d gid=%d", - parent, name, xinode->uid, xinode->gid); + fip->req = req; + fip->inode = parent; + fip->device_id = device_id; + + log_debug("Looking up %s in %s on %d", name, cptr, device_id); + if (dev_redir_lookup_entry((void *) fip, device_id, + cptr, name)) + { + log_error("failed to send dev_redir_lookup_entry() cmd"); + fuse_reply_err(req, EREMOTEIO); + free(fip); + } + } + } } /** @@ -3145,4 +3294,26 @@ xfuse_delete_stale_entries(fuse_ino_t pinode) } } +static void make_fuse_entry_reply(fuse_req_t req, const XRDP_INODE *xinode) +{ + struct fuse_entry_param e; + + memset(&e, 0, sizeof(e)); + e.ino = xinode->inode; + e.attr_timeout = XFUSE_ATTR_TIMEOUT; + e.entry_timeout = XFUSE_ENTRY_TIMEOUT; + e.attr.st_ino = xinode->inode; + e.attr.st_mode = xinode->mode; + e.attr.st_nlink = xinode->nlink; + e.attr.st_uid = xinode->uid; + e.attr.st_gid = xinode->gid; + e.attr.st_size = xinode->size; + e.attr.st_atime = xinode->atime; + e.attr.st_mtime = xinode->mtime; + e.attr.st_ctime = xinode->ctime; + e.generation = 1; + + fuse_reply_entry(req, &e); +} + #endif /* end else #ifndef XRDP_FUSE */ diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 945a4bef..89fd7095 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -19,29 +19,27 @@ #ifndef _CHANSRV_FUSE_H #define _CHANSRV_FUSE_H -/* a file or dir entry in the xrdp file system */ -struct xrdp_inode +#include "arch.h" + +/* + * a file or dir entry in the xrdp file system (opaque type externally) */ +struct xrdp_inode; + +/* Used to pass file info in to xfuse_devredir_add_file_or_dir() + * + * The string storage the name field points to is only valid + * for the duration of the xfuse_devredir_add_file_or_dir() + * call + */ +struct file_attr { - tui32 parent_inode; /* Parent serial number. */ - tui32 inode; /* File serial number. */ + const char *name; /* Name of file or directory */ tui32 mode; /* File mode. */ - tui32 nlink; /* symbolic link count. */ - tui32 nentries; /* number of entries in a dir */ - tui32 nopen; /* number of simultaneous opens */ - tui32 uid; /* User ID of the file's owner. */ - tui32 gid; /* Group ID of the file's group. */ size_t size; /* Size of file, in bytes. */ time_t atime; /* Time of last access. */ time_t mtime; /* Time of last modification. */ time_t ctime; /* Time of last status change. */ - char name[1024]; /* Dir or filename */ - tui32 device_id; /* for file system redirection */ - int lindex; /* used in clipboard operations */ - int is_loc_resource; /* this is not a redirected resource */ - int close_in_progress; /* close cmd sent to client */ - int stale; /* mark file as stale, ok to remove */ }; -typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode int xfuse_init(void); int xfuse_deinit(void); @@ -55,8 +53,12 @@ int xfuse_file_contents_size(int stream_id, int file_size); int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex); /* functions that are invoked from devredir */ -int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode); +struct xrdp_inode *xfuse_devredir_add_file_or_dir( + void *vp, + const struct file_attr *file_info); void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus); +void xfuse_devredir_cb_lookup_entry(void *vp, tui32 IoStatus, + struct xrdp_inode *xinode); void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId); void xfuse_devredir_cb_write_file( void *vp, diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index e2a29394..6e1130b7 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -91,6 +91,13 @@ } \ } +/* + * Size of structs supported by IRP_MJ_QUERY_INFORMATION without + * trailing RESERVED fields (MS-RDPEFS 2.2.3.3.8) + */ +#define FILE_BASIC_INFORMATION_SIZE 36 +#define FILE_STD_INFORMATION_SIZE 22 + /* globals */ extern int g_rdpdr_chan_id; /* in chansrv.c */ int g_is_printer_redir_supported = 0; @@ -113,6 +120,19 @@ static void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus); static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus); static void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus); static void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus); +static void devredir_proc_cid_lookup_basic_entry(IRP *irp, tui32 IoStatus); +static void devredir_proc_cid_lookup_basic_entry_resp( + IRP *irp, + struct stream *s_in, + tui32 IoStatus); +static void devredir_proc_cid_lookup_std_entry_resp( + IRP *irp, + struct stream *s_in, + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); +/* Other local functions */ +static void lookup_std_entry(IRP *irp); /*****************************************************************************/ int @@ -873,6 +893,27 @@ dev_redir_proc_device_iocompletion(struct stream *s) devredir_proc_cid_rename_file_resp(irp, IoStatus); break; + case CID_LOOKUP_BASIC_ENTRY: + log_debug("got CID_LOOKUP_BASIC_ENTRY"); + xstream_rd_u32_le(s, irp->FileId); + /* Issue a call to get the FileBasicInformation */ + devredir_proc_cid_lookup_basic_entry(irp, IoStatus); + break; + + case CID_LOOKUP_STD_ENTRY: + log_debug("got CID_LOOKUP_STD_ENTRY"); + /* Parse the FileBasicInformation and request the + * FileStandardInformation */ + devredir_proc_cid_lookup_basic_entry_resp(irp, s, IoStatus); + break; + + case CID_LOOKUP_ENTRY_RESP: + /* Parse the FileStandardInformation and respond to caller */ + log_debug("got CID_LOOKUP_ENTRY_RESP"); + devredir_proc_cid_lookup_std_entry_resp(irp, s, DeviceId, + CompletionId, IoStatus); + break; + default: log_error("got unknown CompletionID: DeviceId=0x%x " "CompletionId=0x%x IoStatus=0x%x", @@ -899,7 +940,6 @@ dev_redir_proc_query_dir_response(IRP *irp, tui32 IoStatus) { FUSE_DATA *fuse_data = NULL; - XRDP_INODE *xinode; tui32 Length; tui64 CreationTime; @@ -909,6 +949,7 @@ dev_redir_proc_query_dir_response(IRP *irp, tui32 FileAttributes; tui32 FileNameLength; tui32 status; + struct file_attr fattr; char filename[256]; unsigned int i = 0; @@ -974,25 +1015,16 @@ dev_redir_proc_query_dir_response(IRP *irp, //log_debug("FileNameLength: %d", FileNameLength); log_debug("FileName: %s", filename); - xinode = g_new0(struct xrdp_inode, 1); - if (xinode == NULL) - { - log_error("system out of memory"); - fuse_data = devredir_fuse_data_peek(irp); - xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, NULL); - return; - } - - strcpy(xinode->name, filename); - xinode->size = (size_t) EndOfFile; - xinode->mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes); - xinode->atime = WINDOWS_TO_LINUX_TIME(LastAccessTime); - xinode->mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime); - xinode->ctime = WINDOWS_TO_LINUX_TIME(CreationTime); + fattr.name = filename; + fattr.mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes); + fattr.size = (size_t) EndOfFile; + fattr.atime = WINDOWS_TO_LINUX_TIME(LastAccessTime); + fattr.mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime); + fattr.ctime = WINDOWS_TO_LINUX_TIME(CreationTime); /* add this entry to xrdp file system */ fuse_data = devredir_fuse_data_peek(irp); - xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, xinode); + (void)xfuse_devredir_add_file_or_dir(fuse_data->data_ptr, &fattr); } dev_redir_send_drive_dir_request(irp, DeviceId, 0, NULL); @@ -1055,6 +1087,78 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path) return rval; } +/** + * FUSE calls this function whenever it wants us to lookup a file or directory + * + * @param fusep opaque data struct that we just pass back to FUSE when done + * @param device_id device_id of the redirected share + * @param path the name of the directory containing the file + * @param file the filename + * + * @return 0 on success, -1 on failure + *****************************************************************************/ + +int +dev_redir_lookup_entry(void *fusep, tui32 device_id, const char *dirpath, + const char *entry) +{ + tui32 DesiredAccess; + tui32 CreateOptions; + tui32 CreateDisposition; + int rval = -1; + IRP *irp; + size_t pathlen; + + log_debug("fusep=%p", fusep); + + /* Check the qualified name of the file fits in the IRP */ + pathlen = strlen(dirpath) + strlen(entry); + if (!dev_redir_string_ends_with(dirpath,'/')) + { + ++pathlen; + } + if (pathlen < sizeof(irp->pathname)) + { + if ((irp = devredir_irp_new()) != NULL) + { + strcpy(irp->pathname, dirpath); + if (!dev_redir_string_ends_with(dirpath, '/')) + { + strcat(irp->pathname, "/"); + } + strcat(irp->pathname, entry); + + /* convert / to windows compatible \ */ + devredir_cvt_slash(irp->pathname); + + /* + * Allocate an IRP to open the file, read the basic attributes, + * read the standard attributes, and then close the file + */ + irp->CompletionId = g_completion_id++; + irp->completion_type = CID_LOOKUP_BASIC_ENTRY; + irp->DeviceId = device_id; + + devredir_fuse_data_enqueue(irp, fusep); + + DesiredAccess = DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE; + CreateOptions = 0x020; /* Same as rmdir or file */ + CreateDisposition = CD_FILE_OPEN; + + log_debug("lookup for device_id=%d path=%s", + device_id, irp->pathname); + + rval = dev_redir_send_drive_create_request(device_id, + irp->pathname, + DesiredAccess, CreateOptions, + CreateDisposition, + irp->CompletionId); + } + } + + return rval; +} + int dev_redir_file_open(void *fusep, tui32 device_id, const char *path, int mode, int type, const char *gen_buf) @@ -1073,7 +1177,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, const char *path, if (type & OP_RENAME_FILE) { irp->completion_type = CID_RENAME_FILE; - strncpy(irp->gen_buf, gen_buf, 1023); + strncpy(irp->gen.buf, gen_buf, 1023); } else { @@ -1641,7 +1745,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) } /* Path in unicode needs this much space */ - flen = ((g_mbstowcs(NULL, irp->gen_buf, 0) * sizeof(twchar)) / 2) + 2; + flen = ((g_mbstowcs(NULL, irp->gen.buf, 0) * sizeof(twchar)) / 2) + 2; sblen = 6 + flen; xstream_new(s, 1024 + flen); @@ -1659,7 +1763,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) xstream_wr_u32_le(s, flen); /* FileNameLength */ /* filename in unicode */ - devredir_cvt_to_unicode(s->p, irp->gen_buf); /* UNICODE_TODO */ + devredir_cvt_to_unicode(s->p, irp->gen.buf); /* UNICODE_TODO */ xstream_seek(s, flen); /* send to client */ @@ -1698,3 +1802,192 @@ devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus) irp->CompletionId, IRP_MJ_CLOSE, 0, 32); } + +static void +devredir_proc_cid_lookup_basic_entry(IRP *irp, tui32 IoStatus) +{ + struct stream *s; + int bytes; + + if (IoStatus != NT_STATUS_SUCCESS) + { + log_debug("lookup returned with IoStatus=0x%08x", IoStatus); + + FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp); + if (fuse_data) + { + xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, NULL); + free(fuse_data); + } + devredir_irp_delete(irp); + } + else + { + xstream_new(s, 1024); + + irp->completion_type = CID_LOOKUP_STD_ENTRY; + devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId, + irp->CompletionId, + IRP_MJ_QUERY_INFORMATION, 0); + + xstream_wr_u32_le(s, FileBasicInformation); + xstream_wr_u32_le(s, FILE_BASIC_INFORMATION_SIZE); + /* buffer length */ + xstream_seek(s, 24); /* padding */ + xstream_seek(s, FILE_BASIC_INFORMATION_SIZE); + /* buffer */ + /* send to client */ + bytes = xstream_len(s); + send_channel_data(g_rdpdr_chan_id, s->data, bytes); + xstream_free(s); + } +} + +static void +devredir_proc_cid_lookup_basic_entry_resp(IRP *irp, + struct stream *s_in, + tui32 IoStatus) +{ + tui32 Length = 0; + tui64 CreationTime; + tui64 LastAccessTime; + tui64 LastWriteTime; + tui32 FileAttributes; + + log_debug("basic_lookup returned with IoStatus=0x%08x", IoStatus); + + /* Data as we expect? */ + if (IoStatus == NT_STATUS_SUCCESS) + { + xstream_rd_u32_le(s_in, Length); + if (Length != FILE_BASIC_INFORMATION_SIZE) + { + log_error("Expected FILE_BASIC_OPEN_INFORMATION data but len=%d", + Length); + } + } + + if (IoStatus != NT_STATUS_SUCCESS || + Length != FILE_BASIC_INFORMATION_SIZE) + { + /* Return a lookup fail to the FUSE caller */ + FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp); + if (fuse_data) + { + xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, NULL); + free(fuse_data); + } + devredir_irp_delete(irp); + } + else + { + log_debug("processing FILE_BASIC_INFORMATION"); + + xstream_rd_u64_le(s_in, CreationTime); + xstream_rd_u64_le(s_in, LastAccessTime); + xstream_rd_u64_le(s_in, LastWriteTime); + xstream_seek(s_in, 8); /* ChangeTime */ + xstream_rd_u32_le(s_in, FileAttributes); + + //log_debug("CreationTime: 0x%llx", + // (unsigned long long)CreationTime); + //log_debug("LastAccessTime: 0x%llx", + // (unsigned long long)LastAccessTime); + //log_debug("LastWriteTime: 0x%llx", + // (unsigned long long)LastWriteTime); + //log_debug("FileAttributes: 0x%x", (unsigned int)FileAttributes); + + /* Save the basic attributes in the IRP */ + irp->gen.fattr.mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes); + irp->gen.fattr.atime = WINDOWS_TO_LINUX_TIME(LastAccessTime); + irp->gen.fattr.mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime); + irp->gen.fattr.ctime = WINDOWS_TO_LINUX_TIME(CreationTime); + + /* Re-use the IRP to lookup the FileStandardInformation */ + lookup_std_entry(irp); + } +} + +static void +lookup_std_entry(IRP *irp) +{ + struct stream *s; + int bytes; + + xstream_new(s, 1024); + + irp->completion_type = CID_LOOKUP_ENTRY_RESP; + devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId, + irp->CompletionId, + IRP_MJ_QUERY_INFORMATION, 0); + + xstream_wr_u32_le(s, FileStandardInformation); + xstream_wr_u32_le(s, FILE_STD_INFORMATION_SIZE); + /* buffer length */ + xstream_seek(s, 24); /* padding */ + xstream_seek(s, FILE_STD_INFORMATION_SIZE); + /* buffer */ + /* send to client */ + bytes = xstream_len(s); + send_channel_data(g_rdpdr_chan_id, s->data, bytes); + xstream_free(s); +} + +static void +devredir_proc_cid_lookup_std_entry_resp(IRP *irp, + struct stream *s_in, + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus) +{ + FUSE_DATA *fuse_data; + tui32 Length; + tui64 EndOfFile; + struct xrdp_inode *xinode = NULL; + + fuse_data = devredir_fuse_data_dequeue(irp); + if (!fuse_data) + { + log_error("fuse_data unexpectedly NULL!"); + } + else + { + if (IoStatus == NT_STATUS_SUCCESS) + { + /* Data as we expect? */ + xstream_rd_u32_le(s_in, Length); + if (Length != FILE_STD_INFORMATION_SIZE) + { + log_error("Expected FILE_STD_OPEN_INFORMATION data but len=%d", + Length); + } + else + { + log_debug("processing FILE_STD_INFORMATION"); + xstream_seek(s_in, 8); /* AllocationSize */ + xstream_rd_u64_le(s_in, EndOfFile); + //log_debug("EndOfFile: %lld", + // (unsigned long long)EndOfFile); + + /* Finish the attribute block off and add the file */ + irp->gen.fattr.size = EndOfFile; + irp->gen.fattr.name = strrchr(irp->pathname,'\\') + 1; + + xinode = xfuse_devredir_add_file_or_dir(fuse_data->data_ptr, + &irp->gen.fattr); + } + } + + xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, xinode); + free(fuse_data); + } + + /* Close the file handle */ + irp->completion_type = CID_CLOSE; + dev_redir_send_drive_close_request(RDPDR_CTYP_CORE, + PAKID_CORE_DEVICE_IOREQUEST, + irp->DeviceId, + irp->FileId, + irp->CompletionId, + IRP_MJ_CLOSE, 0, 32); +} diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h index 00ed5dda..8042347c 100644 --- a/sesman/chansrv/devredir.h +++ b/sesman/chansrv/devredir.h @@ -92,6 +92,9 @@ void devredir_insert_RDPDR_header(struct stream *s, tui16 Component, /* called from FUSE module */ int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path); +int dev_redir_lookup_entry(void *fusep, tui32 device_id, const char *dirpath, + const char *entry); + int dev_redir_file_open(void *fusep, tui32 device_id, const char *path, int mode, int type, const char *gen_buf); @@ -255,11 +258,12 @@ enum CREATE_OPTIONS #define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002 /* - * NTSTATUS codes (used by IoStatus) + * NTSTATUS codes (used by IoStatus) - see section 2.3 of MS-ERREF */ #define NT_STATUS_SUCCESS 0x00000000 #define NT_STATUS_UNSUCCESSFUL 0xC0000001 +#define NT_STATUS_NO_SUCH_FILE 0xC000000F #define NT_STATUS_ACCESS_DENIED 0xC0000022 #define NT_STATUS_OBJECT_NAME_INVALID 0xC0000033 #define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034 @@ -287,12 +291,16 @@ enum COMPLETION_ID CID_RMDIR_OR_FILE, CID_RMDIR_OR_FILE_RESP, CID_RENAME_FILE, - CID_RENAME_FILE_RESP + CID_RENAME_FILE_RESP, + CID_LOOKUP_BASIC_ENTRY, + CID_LOOKUP_STD_ENTRY, + CID_LOOKUP_ENTRY_RESP }; enum FS_INFORMATION_CLASS { FileBasicInformation = 0x00000004, /* set atime, mtime, ctime etc */ + FileStandardInformation = 0x00000005, /* Alloc size, EOF #links, etc */ FileEndOfFileInformation = 0x00000014, /* set EOF info */ FileDispositionInformation = 0x0000000D, /* mark a file for deletion */ FileRenameInformation = 0x0000000A, /* rename a file */ diff --git a/sesman/chansrv/irp.h b/sesman/chansrv/irp.h index 39840a16..8fd3b91e 100644 --- a/sesman/chansrv/irp.h +++ b/sesman/chansrv/irp.h @@ -24,6 +24,8 @@ #ifndef __IRP_H #define __IRP_H +#include "chansrv_fuse.h" + typedef struct fuse_data FUSE_DATA; struct fuse_data { @@ -42,7 +44,11 @@ struct irp tui32 FileId; /* RDP client provided unique number */ char completion_type; /* describes I/O type */ char pathname[256]; /* absolute pathname */ - char gen_buf[1024]; /* for general use */ + union + { + char buf[1024]; /* General character data */ + struct file_attr fattr; /* Used to assemble file attributes */ + } gen; /* for general use */ int type; FUSE_DATA *fd_head; /* point to first FUSE opaque object */ FUSE_DATA *fd_tail; /* point to last FUSE opaque object */ From 0ed82f71e8b3208d12f164ea8900195cd868032e Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 31 Mar 2019 21:54:09 -0700 Subject: [PATCH 19/23] xrdp: check term event for more responsive shutdown --- common/trans.c | 20 ++++++++++++++++++-- xrdp/xrdp_mm.c | 10 ++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/common/trans.c b/common/trans.c index 5909e4eb..0882d643 100644 --- a/common/trans.c +++ b/common/trans.c @@ -712,13 +712,21 @@ trans_connect(struct trans *self, const char *server, const char *port, now = g_time3(); if (now - start_time < timeout) { - g_sleep(timeout / 5); + g_sleep(100); } else { self->status = TRANS_STATUS_DOWN; return 1; } + if (self->is_term != NULL) + { + if (self->is_term()) + { + self->status = TRANS_STATUS_DOWN; + return 1; + } + } } } } @@ -748,13 +756,21 @@ trans_connect(struct trans *self, const char *server, const char *port, now = g_time3(); if (now - start_time < timeout) { - g_sleep(timeout / 5); + g_sleep(100); } else { self->status = TRANS_STATUS_DOWN; return 1; } + if (self->is_term != NULL) + { + if (self->is_term()) + { + self->status = TRANS_STATUS_DOWN; + return 1; + } + } } } } diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 7d204b5b..757620ac 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1440,7 +1440,10 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port) self->chan_trans_up = 1; break; } - + if (g_is_term()) + { + break; + } g_sleep(1000); log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: connect failed " "trying again..."); @@ -2275,7 +2278,10 @@ xrdp_mm_connect(struct xrdp_mm *self) ok = 1; break; } - + if (g_is_term()) + { + break; + } g_sleep(1000); g_writeln("xrdp_mm_connect: connect failed " "trying again..."); From 6a6442e32ffd71bf293cf544d27be4df6cfb837f Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Tue, 2 Apr 2019 13:08:47 +0100 Subject: [PATCH 20/23] Fix sing symbol link error when --disable-fuse is set --- sesman/chansrv/chansrv_fuse.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 3e8bcab5..dca1e9f2 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -77,6 +77,10 @@ struct xrdp_inode *xfuse_devredir_add_file_or_dir( const struct file_attr *fattr) { return NULL;} void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {} +void xfuse_devredir_cb_lookup_entry(void *vp, + tui32 IoStatus, + struct xrdp_inode *xinode) + {} void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {} void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {} void xfuse_devredir_cb_file_close(void *vp) {} From fe97b983f532ee81c58cbcafd47b7021832549d6 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 11 Apr 2019 11:28:33 +0100 Subject: [PATCH 21/23] Remove unnecessary reference from sesman/config.c Following commit 81703c426f8498022c28a231df7d88ca28bfa842, there are no longer any references to g_cfg from within this file, and so the external reference can be removed. --- sesman/config.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sesman/config.c b/sesman/config.c index cce75bf2..ebadfd83 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -34,8 +34,6 @@ #include "sesman.h" #include "log.h" -extern struct config_sesman *g_cfg; /* in sesman.c */ - /******************************************************************************/ From d6e2dbe82df4e1be281c4dd3d3bbee19b16af519 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 18 Apr 2019 10:22:53 +0900 Subject: [PATCH 22/23] Bump to v0.9.10 --- README.md | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fec7ee66..3e53b1f4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp) ![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg) -*Current Version:* 0.9.9 +*Current Version:* 0.9.10 # xrdp - an open source RDP server diff --git a/configure.ac b/configure.ac index 4dbcf230..b2936a9d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script AC_PREREQ(2.65) -AC_INIT([xrdp], [0.9.9], [xrdp-devel@googlegroups.com]) +AC_INIT([xrdp], [0.9.10], [xrdp-devel@googlegroups.com]) AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in) AM_INIT_AUTOMAKE([1.7.2 foreign]) AC_CONFIG_MACRO_DIR([m4]) From 0e0d985bc52fbe736fc71f80a4785c7931c502d9 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 18 Apr 2019 10:51:45 +0900 Subject: [PATCH 23/23] Update NEWS for v0.9.10 --- NEWS.md | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7c761a5c..f9afe68e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,29 +1,59 @@ -# Release notes for xrdp v0.9.9 (2018/12/25) +# Release notes for xrdp v0.9.10 (2019/04/18) -# Release cycle +## Special thanks +Thank you for matt335672 contributing to lots of improvements in drive redirection! + +## New features +* Restrict outbound (server->client) clipboard transfer, configured in `sesman.ini` #1298 + +## Bug fixes +* Fix the issue libscp v1 not setting width but height twice #1293 +* Fix the issue reconnecting to session causes duplicate drive entries in fuse fs #1299 +* Fix default_wm and reconnect_sh refer wrong path after sesman caught SIGUP #1315 #1331 +* Shutdown xrdp more responsively #1325 +* Improve remote file lookup in drive redirection #996 #1327 +* Overwriting & appending to existing files is are now supported #1327 + +## Other changes +* Add Danish Keyboard #1290 +* Put xrdp- prefix to some executables appear in man page #1313 +* Replace some URLs from SF.net to xrdp.org #1313 + +## Known issues +* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to + xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266 +* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965 + +----------------------- + +## Release notes for xrdp v0.9.9 (2018/12/25) + +## Release cycle From the next release, release cycle will be changed from quarterly to every 4 months. xrdp will be released in April, August, December. -# New features +## New features * Disconnection by idle timeout (requires xorgxrdp v0.2.9 or later) #1227 * Glyph cache v2 (fixes no font issue on iOS/macOS/Android client) #367 #1235 -# Bug fixes +## Bug fixes * Fix xrdp-chansrv crashes caused in drive redirection #1202 #1225 * Fix build with FDK AAC v2 #1257 * Do not enable RemoteApp if the INFO_RAIL flag is not set (RDP-RDP proxy) #1253 -# Other changes +## Other changes * Add Spanish Latin Amarican keyboard #1237 #1240 #1244 * Dynamic channel improvements #1222 #1224 * Remove some deprecated sesman session types #1232 * Refactoring and cleanups -# Known issues +## Known issues * FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266 * Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965 +----------------------- + # Release notes for xrdp v0.9.8 (2018/09/25) ## Deprecation notice