/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 828 by stargo, Sun Mar 6 21:11:18 2005 UTC revision 1042 by astrand, Tue Jan 24 12:40:24 2006 UTC
# Line 19  Line 19 
19  */  */
20    
21  #include <time.h>  #include <time.h>
22    #include <errno.h>
23    #include <unistd.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26    #ifdef HAVE_ICONV
27    #ifdef HAVE_ICONV_H
28    #include <iconv.h>
29    #endif
30    
31    #ifndef ICONV_CONST
32    #define ICONV_CONST ""
33    #endif
34    #endif
35    
36  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
37  extern char g_username[16];  extern char g_username[64];
38    extern char g_codepage[16];
39  extern BOOL g_bitmap_compression;  extern BOOL g_bitmap_compression;
40  extern BOOL g_orders;  extern BOOL g_orders;
41  extern BOOL g_encryption;  extern BOOL g_encryption;
42  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
43    extern BOOL g_polygon_ellipse_orders;
44  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
45  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
46  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
47  extern int g_server_bpp;  extern int g_server_depth;
48  extern int g_width;  extern int g_width;
49  extern int g_height;  extern int g_height;
50  extern BOOL g_bitmap_cache;  extern BOOL g_bitmap_cache;
# Line 41  uint32 g_rdp_shareid; Line 55  uint32 g_rdp_shareid;
55    
56  extern RDPCOMP g_mppc_dict;  extern RDPCOMP g_mppc_dict;
57    
58    /* Session Directory support */
59    extern BOOL g_redirect;
60    extern char g_redirect_server[64];
61    extern char g_redirect_domain[16];
62    extern char g_redirect_password[64];
63    extern char g_redirect_username[64];
64    extern char g_redirect_cookie[128];
65    extern uint32 g_redirect_flags;
66    /* END Session Directory support */
67    
68  #if WITH_DEBUG  #if WITH_DEBUG
69  static uint32 g_packetno;  static uint32 g_packetno;
70  #endif  #endif
71    
72    #ifdef HAVE_ICONV
73    static BOOL g_iconv_works = True;
74    #endif
75    
76  /* Receive an RDP packet */  /* Receive an RDP packet */
77  static STREAM  static STREAM
78  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
# Line 53  rdp_recv(uint8 * type) Line 81  rdp_recv(uint8 * type)
81          uint16 length, pdu_type;          uint16 length, pdu_type;
82          uint8 rdpver;          uint8 rdpver;
83    
84          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
85          {          {
86                  rdp_s = sec_recv(&rdpver);                  rdp_s = sec_recv(&rdpver);
87                  if (rdp_s == NULL)                  if (rdp_s == NULL)
# Line 140  rdp_send_data(STREAM s, uint8 data_pdu_t Line 168  rdp_send_data(STREAM s, uint8 data_pdu_t
168  void  void
169  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
170  {  {
171          int i = 0, j = 0;  #ifdef HAVE_ICONV
172            size_t ibl = strlen(string), obl = len + 2;
173            static iconv_t iconv_h = (iconv_t) - 1;
174            char *pin = string, *pout = (char *) s->p;
175    
176          len += 2;          memset(pout, 0, len + 4);
177    
178          while (i < len)          if (g_iconv_works)
179          {          {
180                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
181                  s->p[i++] = 0;                  {
182                            size_t i = 1, o = 4;
183                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
184                            {
185                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
186                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
187    
188                                    g_iconv_works = False;
189                                    rdp_out_unistr(s, string, len);
190                                    return;
191                            }
192                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
193                                (size_t) - 1)
194                            {
195                                    iconv_close(iconv_h);
196                                    iconv_h = (iconv_t) - 1;
197                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
198    
199                                    g_iconv_works = False;
200                                    rdp_out_unistr(s, string, len);
201                                    return;
202                            }
203                            pin = string;
204                            pout = (char *) s->p;
205                    }
206    
207                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
208                    {
209                            iconv_close(iconv_h);
210                            iconv_h = (iconv_t) - 1;
211                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
212    
213                            g_iconv_works = False;
214                            rdp_out_unistr(s, string, len);
215                            return;
216                    }
217    
218                    s->p += len + 2;
219    
220          }          }
221            else
222    #endif
223            {
224                    int i = 0, j = 0;
225    
226                    len += 2;
227    
228          s->p += len;                  while (i < len)
229                    {
230                            s->p[i++] = string[j++];
231                            s->p[i++] = 0;
232                    }
233    
234                    s->p += len;
235            }
236  }  }
237    
238  /* Input a string in Unicode  /* Input a string in Unicode
# Line 160  rdp_out_unistr(STREAM s, char *string, i Line 242  rdp_out_unistr(STREAM s, char *string, i
242  int  int
243  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int uni_len)
244  {  {
245          int i = 0;  #ifdef HAVE_ICONV
246            size_t ibl = uni_len, obl = uni_len;
247            char *pin = (char *) s->p, *pout = string;
248            static iconv_t iconv_h = (iconv_t) - 1;
249    
250          while (i < uni_len / 2)          if (g_iconv_works)
251          {          {
252                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
253                  in_uint8s(s, 1);                  {
254                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
255                            {
256                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
257                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
258    
259                                    g_iconv_works = False;
260                                    return rdp_in_unistr(s, string, uni_len);
261                            }
262                    }
263    
264                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
265                    {
266                            iconv_close(iconv_h);
267                            iconv_h = (iconv_t) - 1;
268                            warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
269    
270                            g_iconv_works = False;
271                            return rdp_in_unistr(s, string, uni_len);
272                    }
273    
274                    /* we must update the location of the current STREAM for future reads of s->p */
275                    s->p += uni_len;
276    
277                    return pout - string;
278          }          }
279            else
280    #endif
281            {
282                    int i = 0;
283    
284                    while (i < uni_len / 2)
285                    {
286                            in_uint8a(s, &string[i++], 1);
287                            in_uint8s(s, 1);
288                    }
289    
290          return i - 1;                  return i - 1;
291            }
292  }  }
293    
294    
# Line 191  rdp_send_logon_info(uint32 flags, char * Line 311  rdp_send_logon_info(uint32 flags, char *
311          time_t t = time(NULL);          time_t t = time(NULL);
312          time_t tzone;          time_t tzone;
313    
 #if 0  
         /* enable rdp compression */  
         /* some problems still exist with rdp5 */  
         flags |= RDP_COMPRESSION;  
 #endif  
   
314          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
315          {          {
316                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
# Line 381  rdp_send_input(uint32 time, uint16 messa Line 495  rdp_send_input(uint32 time, uint16 messa
495          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
496  }  }
497    
498  /* Inform the server on the contents of the persistent bitmap cache */  /* Send a client window information PDU */
499    void
500    rdp_send_client_window_status(int status)
501    {
502            STREAM s;
503            static int current_status = 1;
504    
505            if (current_status == status)
506                    return;
507    
508            s = rdp_init_data(12);
509    
510            out_uint32_le(s, status);
511    
512            switch (status)
513            {
514                    case 0: /* shut the server up */
515                            break;
516    
517                    case 1: /* receive data again */
518                            out_uint32_le(s, 0);    /* unknown */
519                            out_uint16_le(s, g_width);
520                            out_uint16_le(s, g_height);
521                            break;
522            }
523    
524            s_mark_end(s);
525            rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
526            current_status = status;
527    }
528    
529    /* Send persistent bitmap cache enumeration PDU's */
530  static void  static void
531  rdp_enum_bmpcache2(void)  rdp_enum_bmpcache2(void)
532  {  {
533          STREAM s;          STREAM s;
534          uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];          HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
535          uint32 nids, offset, count, flags;          uint32 num_keys, offset, count, flags;
536    
537          offset = 0;          offset = 0;
538          nids = pstcache_enumerate(2, idlist);          num_keys = pstcache_enumerate(2, keylist);
539    
540          while (offset < nids)          while (offset < num_keys)
541          {          {
542                  count = MIN(nids - offset, 169);                  count = MIN(num_keys - offset, 169);
543    
544                  s = rdp_init_data(24 + count * sizeof(BITMAP_ID));                  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
545    
546                  flags = 0;                  flags = 0;
547                  if (offset == 0)                  if (offset == 0)
548                          flags |= PDU_FLAG_FIRST;                          flags |= PDU_FLAG_FIRST;
549                  if (nids - offset <= 169)                  if (num_keys - offset <= 169)
550                          flags |= PDU_FLAG_LAST;                          flags |= PDU_FLAG_LAST;
551    
552                  /* header */                  /* header */
# Line 411  rdp_enum_bmpcache2(void) Line 556  rdp_enum_bmpcache2(void)
556                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
557                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
558                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
559                  out_uint16_le(s, nids);                  out_uint16_le(s, num_keys);
560                  out_uint32_le(s, 0);                  out_uint32_le(s, 0);
561                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
562    
563                  /* list */                  /* list */
564                  out_uint8a(s, idlist + offset * sizeof(BITMAP_ID), count * sizeof(BITMAP_ID));                  out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
565    
566                  s_mark_end(s);                  s_mark_end(s);
567                  rdp_send_data(s, 0x2b);                  rdp_send_data(s, 0x2b);
# Line 475  rdp_out_bitmap_caps(STREAM s) Line 620  rdp_out_bitmap_caps(STREAM s)
620          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
621          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
622    
623          out_uint16_le(s, g_server_bpp); /* Preferred BPP */          out_uint16_le(s, g_server_depth);       /* Preferred colour depth */
624          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
625          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
626          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
# Line 495  rdp_out_order_caps(STREAM s) Line 640  rdp_out_order_caps(STREAM s)
640  {  {
641          uint8 order_caps[32];          uint8 order_caps[32];
642    
   
643          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
644          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
645          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
646          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
647          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
648            order_caps[4] = 0;      /* triblt */
649          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
650          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
651          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
652          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
653          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
654          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
655            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
656            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
657          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
658            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
659            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
660          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
661          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
662          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 535  rdp_out_bmpcache_caps(STREAM s) Line 684  rdp_out_bmpcache_caps(STREAM s)
684          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
685          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
686    
687          Bpp = (g_server_bpp + 7) / 8;          Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
688          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
689          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
690          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
# Line 554  rdp_out_bmpcache2_caps(STREAM s) Line 703  rdp_out_bmpcache2_caps(STREAM s)
703    
704          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
705    
706          out_uint16_le(s, 0x0300);       /* flags? number of caches? */          out_uint16_be(s, 3);    /* number of caches in this set */
707    
708            /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
709          out_uint32_le(s, BMPCACHE2_C0_CELLS);          out_uint32_le(s, BMPCACHE2_C0_CELLS);
710          out_uint32_le(s, BMPCACHE2_C1_CELLS);          out_uint32_le(s, BMPCACHE2_C1_CELLS);
711          if (pstcache_init(2))          if (pstcache_init(2))
# Line 731  rdp_process_general_caps(STREAM s) Line 881  rdp_process_general_caps(STREAM s)
881  static void  static void
882  rdp_process_bitmap_caps(STREAM s)  rdp_process_bitmap_caps(STREAM s)
883  {  {
884          uint16 width, height, bpp;          uint16 width, height, depth;
885    
886          in_uint16_le(s, bpp);          in_uint16_le(s, depth);
887          in_uint8s(s, 6);          in_uint8s(s, 6);
888    
889          in_uint16_le(s, width);          in_uint16_le(s, width);
890          in_uint16_le(s, height);          in_uint16_le(s, height);
891    
892          DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));          DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
893    
894          /*          /*
895           * The server may limit bpp and change the size of the desktop (for           * The server may limit depth and change the size of the desktop (for
896           * example when shadowing another session).           * example when shadowing another session).
897           */           */
898          if (g_server_bpp != bpp)          if (g_server_depth != depth)
899          {          {
900                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);                  warning("Remote desktop does not support colour depth %d; falling back to %d\n",
901                  g_server_bpp = bpp;                          g_server_depth, depth);
902                    g_server_depth = depth;
903          }          }
904          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
905          {          {
906                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,                  warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
907                          width, height);                          width, height);
908                  g_width = width;                  g_width = width;
909                  g_height = height;                  g_height = height;
# Line 761  rdp_process_bitmap_caps(STREAM s) Line 912  rdp_process_bitmap_caps(STREAM s)
912  }  }
913    
914  /* Process server capabilities */  /* Process server capabilities */
915  void  static void
916  rdp_process_server_caps(STREAM s, uint16 length)  rdp_process_server_caps(STREAM s, uint16 length)
917  {  {
918          int n;          int n;
# Line 1096  process_data_pdu(STREAM s, uint32 * ext_ Line 1247  process_data_pdu(STREAM s, uint32 * ext_
1247                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1248                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1249    
1250                  //len -= 18;                  /* len -= 18; */
1251    
1252                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1253                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1148  process_data_pdu(STREAM s, uint32 * ext_ Line 1299  process_data_pdu(STREAM s, uint32 * ext_
1299          return False;          return False;
1300  }  }
1301    
1302    /* Process redirect PDU from Session Directory */
1303    static BOOL
1304    process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1305    {
1306            uint32 len;
1307    
1308            /* these 2 bytes are unknown, seem to be zeros */
1309            in_uint8s(s, 2);
1310    
1311            /* read connection flags */
1312            in_uint32_le(s, g_redirect_flags);
1313    
1314            /* read length of ip string */
1315            in_uint32_le(s, len);
1316    
1317            /* read ip string */
1318            rdp_in_unistr(s, g_redirect_server, len);
1319    
1320            /* read length of cookie string */
1321            in_uint32_le(s, len);
1322    
1323            /* read cookie string (plain ASCII) */
1324            in_uint8a(s, g_redirect_cookie, len);
1325            g_redirect_cookie[len] = 0;
1326    
1327            /* read length of username string */
1328            in_uint32_le(s, len);
1329    
1330            /* read username string */
1331            rdp_in_unistr(s, g_redirect_username, len);
1332    
1333            /* read length of domain string */
1334            in_uint32_le(s, len);
1335    
1336            /* read domain string */
1337            rdp_in_unistr(s, g_redirect_domain, len);
1338    
1339            /* read length of password string */
1340            in_uint32_le(s, len);
1341    
1342            /* read password string */
1343            rdp_in_unistr(s, g_redirect_password, len);
1344    
1345            g_redirect = True;
1346    
1347            return True;
1348    }
1349    
1350  /* Process incoming packets */  /* Process incoming packets */
1351  /* nevers gets out of here till app is done */  /* nevers gets out of here till app is done */
1352  void  void
# Line 1181  rdp_loop(BOOL * deactivated, uint32 * ex Line 1380  rdp_loop(BOOL * deactivated, uint32 * ex
1380                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1381                                  *deactivated = True;                                  *deactivated = True;
1382                                  break;                                  break;
1383                            case RDP_PDU_REDIRECT:
1384                                    return process_redirect_pdu(s);
1385                                    break;
1386                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1387                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1388                                  break;                                  break;
# Line 1208  rdp_connect(char *server, uint32 flags, Line 1410  rdp_connect(char *server, uint32 flags,
1410          return True;          return True;
1411  }  }
1412    
1413    /* Establish a reconnection up to the RDP layer */
1414    BOOL
1415    rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1416                  char *command, char *directory, char *cookie)
1417    {
1418            if (!sec_reconnect(server))
1419                    return False;
1420    
1421            rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1422            return True;
1423    }
1424    
1425    /* Called during redirection to reset the state to support redirection */
1426    void
1427    rdp_reset_state(void)
1428    {
1429            g_next_packet = NULL;   /* reset the packet information */
1430            g_rdp_shareid = 0;
1431            sec_reset_state();
1432    }
1433    
1434  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1435  void  void
1436  rdp_disconnect(void)  rdp_disconnect(void)

Legend:
Removed from v.828  
changed lines
  Added in v.1042

  ViewVC Help
Powered by ViewVC 1.1.26