/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdp.c

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

sourceforge.net/trunk/rdesktop/rdp.c revision 1042 by astrand, Tue Jan 24 12:40:24 2006 UTC jpeg/rdesktop/trunk/rdp.c revision 1507 by dpavlin, Mon Jul 20 16:45:11 2009 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2005     Copyright (C) Matthew Chapman 1999-2008
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 19  Line 19 
19  */  */
20    
21  #include <time.h>  #include <time.h>
22    #ifndef _WIN32
23  #include <errno.h>  #include <errno.h>
24  #include <unistd.h>  #include <unistd.h>
25    #endif
26  #include "rdesktop.h"  #include "rdesktop.h"
27    
28  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
# Line 34  Line 36 
36  #endif  #endif
37    
38  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
39  extern char g_username[64];  extern char *g_username;
40  extern char g_codepage[16];  extern char g_codepage[16];
41  extern BOOL g_bitmap_compression;  extern RD_BOOL g_bitmap_compression;
42  extern BOOL g_orders;  extern RD_BOOL g_orders;
43  extern BOOL g_encryption;  extern RD_BOOL g_encryption;
44  extern BOOL g_desktop_save;  extern RD_BOOL g_desktop_save;
45  extern BOOL g_polygon_ellipse_orders;  extern RD_BOOL g_polygon_ellipse_orders;
46  extern BOOL g_use_rdp5;  extern RD_BOOL g_use_rdp5;
47  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
48  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
49  extern int g_server_depth;  extern int g_server_depth;
50  extern int g_width;  extern int g_width;
51  extern int g_height;  extern int g_height;
52  extern BOOL g_bitmap_cache;  extern RD_BOOL g_bitmap_cache;
53  extern BOOL g_bitmap_cache_persist_enable;  extern RD_BOOL g_bitmap_cache_persist_enable;
54    extern RD_BOOL g_numlock_sync;
55    
56  uint8 *g_next_packet;  uint8 *g_next_packet;
57  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
# Line 56  uint32 g_rdp_shareid; Line 59  uint32 g_rdp_shareid;
59  extern RDPCOMP g_mppc_dict;  extern RDPCOMP g_mppc_dict;
60    
61  /* Session Directory support */  /* Session Directory support */
62  extern BOOL g_redirect;  extern RD_BOOL g_redirect;
63  extern char g_redirect_server[64];  extern char g_redirect_server[64];
64  extern char g_redirect_domain[16];  extern char g_redirect_domain[16];
65  extern char g_redirect_password[64];  extern char g_redirect_password[64];
66  extern char g_redirect_username[64];  extern char *g_redirect_username;
67  extern char g_redirect_cookie[128];  extern char g_redirect_cookie[128];
68  extern uint32 g_redirect_flags;  extern uint32 g_redirect_flags;
69  /* END Session Directory support */  /* END Session Directory support */
# Line 70  static uint32 g_packetno; Line 73  static uint32 g_packetno;
73  #endif  #endif
74    
75  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
76  static BOOL g_iconv_works = True;  static RD_BOOL g_iconv_works = True;
77  #endif  #endif
78    
79  /* Receive an RDP packet */  /* Receive an RDP packet */
# Line 182  rdp_out_unistr(STREAM s, char *string, i Line 185  rdp_out_unistr(STREAM s, char *string, i
185                          size_t i = 1, o = 4;                          size_t i = 1, o = 4;
186                          if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)                          if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
187                          {                          {
188                                  warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",                                  warning("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n",
189                                          g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);                                          g_codepage, WINDOWS_CODEPAGE, iconv_h);
190    
191                                  g_iconv_works = False;                                  g_iconv_works = False;
192                                  rdp_out_unistr(s, string, len);                                  rdp_out_unistr(s, string, len);
# Line 240  rdp_out_unistr(STREAM s, char *string, i Line 243  rdp_out_unistr(STREAM s, char *string, i
243   * Returns str_len of string   * Returns str_len of string
244   */   */
245  int  int
246  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
247  {  {
248  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
249          size_t ibl = uni_len, obl = uni_len;          size_t ibl = in_len, obl = str_size - 1;
250          char *pin = (char *) s->p, *pout = string;          char *pin = (char *) s->p, *pout = string;
251          static iconv_t iconv_h = (iconv_t) - 1;          static iconv_t iconv_h = (iconv_t) - 1;
252    
# Line 253  rdp_in_unistr(STREAM s, char *string, in Line 256  rdp_in_unistr(STREAM s, char *string, in
256                  {                  {
257                          if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)                          if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
258                          {                          {
259                                  warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",                                  warning("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n",
260                                          WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);                                          WINDOWS_CODEPAGE, g_codepage, iconv_h);
261    
262                                  g_iconv_works = False;                                  g_iconv_works = False;
263                                  return rdp_in_unistr(s, string, uni_len);                                  return rdp_in_unistr(s, string, str_size, in_len);
264                          }                          }
265                  }                  }
266    
267                  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)                  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
268                  {                  {
269                          iconv_close(iconv_h);                          if (errno == E2BIG)
270                          iconv_h = (iconv_t) - 1;                          {
271                          warning("rdp_in_unistr: iconv fail, errno %d\n", errno);                                  warning("server sent an unexpectedly long string, truncating\n");
272                            }
273                            else
274                            {
275                                    iconv_close(iconv_h);
276                                    iconv_h = (iconv_t) - 1;
277                                    warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
278    
279                          g_iconv_works = False;                                  g_iconv_works = False;
280                          return rdp_in_unistr(s, string, uni_len);                                  return rdp_in_unistr(s, string, str_size, in_len);
281                            }
282                  }                  }
283    
284                  /* we must update the location of the current STREAM for future reads of s->p */                  /* we must update the location of the current STREAM for future reads of s->p */
285                  s->p += uni_len;                  s->p += in_len;
286    
287                    *pout = 0;
288                  return pout - string;                  return pout - string;
289          }          }
290          else          else
291  #endif  #endif
292          {          {
293                  int i = 0;                  int i = 0;
294                    int len = in_len / 2;
295                    int rem = 0;
296    
297                    if (len > str_size - 1)
298                    {
299                            warning("server sent an unexpectedly long string, truncating\n");
300                            len = str_size - 1;
301                            rem = in_len - 2 * len;
302                    }
303    
304                  while (i < uni_len / 2)                  while (i < len)
305                  {                  {
306                          in_uint8a(s, &string[i++], 1);                          in_uint8a(s, &string[i++], 1);
307                          in_uint8s(s, 1);                          in_uint8s(s, 1);
308                  }                  }
309    
310                  return i - 1;                  in_uint8s(s, rem);
311                    string[len] = 0;
312                    return len;
313          }          }
314  }  }
315    
# Line 435  rdp_send_logon_info(uint32 flags, char * Line 457  rdp_send_logon_info(uint32 flags, char *
457                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
458                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
459                  out_uint32_le(s, g_rdp5_performanceflags);                  out_uint32_le(s, g_rdp5_performanceflags);
460                  out_uint32(s, 0);                  out_uint16(s, 0);
461    
462    
463          }          }
# Line 778  rdp_out_colcache_caps(STREAM s) Line 800  rdp_out_colcache_caps(STREAM s)
800          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
801  }  }
802    
803    /* Output brush cache capability set */
804    static void
805    rdp_out_brushcache_caps(STREAM s)
806    {
807            out_uint16_le(s, RDP_CAPSET_BRUSHCACHE);
808            out_uint16_le(s, RDP_CAPLEN_BRUSHCACHE);
809            out_uint32_le(s, 1);    /* cache type */
810    }
811    
812  static uint8 caps_0x0d[] = {  static uint8 caps_0x0d[] = {
813          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
814          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# Line 827  rdp_send_confirm_active(void) Line 858  rdp_send_confirm_active(void)
858                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
859                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
860                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
861                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +                  RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
862                  4 /* w2k fix, why? */ ;                  4 /* w2k fix, why? */ ;
863    
864          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
# Line 854  rdp_send_confirm_active(void) Line 885  rdp_send_confirm_active(void)
885          rdp_out_control_caps(s);          rdp_out_control_caps(s);
886          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
887          rdp_out_share_caps(s);          rdp_out_share_caps(s);
888            rdp_out_brushcache_caps(s);
889    
890          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
891          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
# Line 971  process_demand_active(STREAM s) Line 1003  process_demand_active(STREAM s)
1003          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
1004          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
1005          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
1006          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
1007                           g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
1008    
1009          if (g_use_rdp5)          if (g_use_rdp5)
1010          {          {
# Line 994  process_colour_pointer_pdu(STREAM s) Line 1027  process_colour_pointer_pdu(STREAM s)
1027  {  {
1028          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y, width, height, cache_idx, masklen, datalen;
1029          uint8 *mask, *data;          uint8 *mask, *data;
1030          HCURSOR cursor;          RD_HCURSOR cursor;
1031    
1032          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
1033          in_uint16_le(s, x);          in_uint16_le(s, x);
# Line 1026  process_system_pointer_pdu(STREAM s) Line 1059  process_system_pointer_pdu(STREAM s)
1059  {  {
1060          uint16 system_pointer_type;          uint16 system_pointer_type;
1061    
1062          in_uint16(s, system_pointer_type);          in_uint16_le(s, system_pointer_type);
1063          switch (system_pointer_type)          switch (system_pointer_type)
1064          {          {
1065                  case RDP_NULL_POINTER:                  case RDP_NULL_POINTER:
# Line 1151  process_palette(STREAM s) Line 1184  process_palette(STREAM s)
1184  {  {
1185          COLOURENTRY *entry;          COLOURENTRY *entry;
1186          COLOURMAP map;          COLOURMAP map;
1187          HCOLOURMAP hmap;          RD_HCOLOURMAP hmap;
1188          int i;          int i;
1189    
1190          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 1221  process_disconnect_pdu(STREAM s, uint32 Line 1254  process_disconnect_pdu(STREAM s, uint32
1254  }  }
1255    
1256  /* Process data PDU */  /* Process data PDU */
1257  static BOOL  static RD_BOOL
1258  process_data_pdu(STREAM s, uint32 * ext_disc_reason)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1259  {  {
1260          uint8 data_pdu_type;          uint8 data_pdu_type;
# Line 1234  process_data_pdu(STREAM s, uint32 * ext_ Line 1267  process_data_pdu(STREAM s, uint32 * ext_
1267          struct stream *ns = &(g_mppc_dict.ns);          struct stream *ns = &(g_mppc_dict.ns);
1268    
1269          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1270          in_uint16(s, len);          in_uint16_le(s, len);
1271          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1272          in_uint8(s, ctype);          in_uint8(s, ctype);
1273          in_uint16(s, clen);          in_uint16_le(s, clen);
1274          clen -= 18;          clen -= 18;
1275    
1276          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
# Line 1291  process_data_pdu(STREAM s, uint32 * ext_ Line 1324  process_data_pdu(STREAM s, uint32 * ext_
1324    
1325                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1326                          process_disconnect_pdu(s, ext_disc_reason);                          process_disconnect_pdu(s, ext_disc_reason);
1327                          return True;  
1328                            /* We used to return true and disconnect immediately here, but
1329                             * Windows Vista sends a disconnect PDU with reason 0 when
1330                             * reconnecting to a disconnected session, and MSTSC doesn't
1331                             * drop the connection.  I think we should just save the status.
1332                             */
1333                            break;
1334    
1335                  default:                  default:
1336                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
# Line 1300  process_data_pdu(STREAM s, uint32 * ext_ Line 1339  process_data_pdu(STREAM s, uint32 * ext_
1339  }  }
1340    
1341  /* Process redirect PDU from Session Directory */  /* Process redirect PDU from Session Directory */
1342  static BOOL  static RD_BOOL
1343  process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )  process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1344  {  {
1345          uint32 len;          uint32 len;
# Line 1315  process_redirect_pdu(STREAM s /*, uint32 Line 1354  process_redirect_pdu(STREAM s /*, uint32
1354          in_uint32_le(s, len);          in_uint32_le(s, len);
1355    
1356          /* read ip string */          /* read ip string */
1357          rdp_in_unistr(s, g_redirect_server, len);          rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
1358    
1359          /* read length of cookie string */          /* read length of cookie string */
1360          in_uint32_le(s, len);          in_uint32_le(s, len);
1361    
1362          /* read cookie string (plain ASCII) */          /* read cookie string (plain ASCII) */
1363          in_uint8a(s, g_redirect_cookie, len);          if (len > sizeof(g_redirect_cookie) - 1)
1364            {
1365                    uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
1366                    len = sizeof(g_redirect_cookie) - 1;
1367    
1368                    warning("Unexpectedly large redirection cookie\n");
1369                    in_uint8a(s, g_redirect_cookie, len);
1370                    in_uint8s(s, rem);
1371            }
1372            else
1373            {
1374                    in_uint8a(s, g_redirect_cookie, len);
1375            }
1376          g_redirect_cookie[len] = 0;          g_redirect_cookie[len] = 0;
1377    
1378          /* read length of username string */          /* read length of username string */
1379          in_uint32_le(s, len);          in_uint32_le(s, len);
1380    
1381          /* read username string */          /* read username string */
1382          rdp_in_unistr(s, g_redirect_username, len);          g_redirect_username = (char *) xmalloc(len + 1);
1383            rdp_in_unistr(s, g_redirect_username, strlen(g_redirect_username), len);
1384    
1385          /* read length of domain string */          /* read length of domain string */
1386          in_uint32_le(s, len);          in_uint32_le(s, len);
1387    
1388          /* read domain string */          /* read domain string */
1389          rdp_in_unistr(s, g_redirect_domain, len);          rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
1390    
1391          /* read length of password string */          /* read length of password string */
1392          in_uint32_le(s, len);          in_uint32_le(s, len);
1393    
1394          /* read password string */          /* read password string */
1395          rdp_in_unistr(s, g_redirect_password, len);          rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
1396    
1397          g_redirect = True;          g_redirect = True;
1398    
# Line 1350  process_redirect_pdu(STREAM s /*, uint32 Line 1402  process_redirect_pdu(STREAM s /*, uint32
1402  /* Process incoming packets */  /* Process incoming packets */
1403  /* nevers gets out of here till app is done */  /* nevers gets out of here till app is done */
1404  void  void
1405  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1406  {  {
1407          while (rdp_loop(deactivated, ext_disc_reason))          while (rdp_loop(deactivated, ext_disc_reason))
1408                  ;                  ;
1409  }  }
1410    
1411  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1412  BOOL  RD_BOOL
1413  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1414  {  {
1415          uint8 type;          uint8 type;
1416          BOOL disc = False;      /* True when a disconnect PDU was received */          RD_BOOL disc = False;   /* True when a disconnect PDU was received */
1417          BOOL cont = True;          RD_BOOL cont = True;
1418          STREAM s;          STREAM s;
1419    
1420          while (cont)          while (cont)
# Line 1399  rdp_loop(BOOL * deactivated, uint32 * ex Line 1451  rdp_loop(BOOL * deactivated, uint32 * ex
1451  }  }
1452    
1453  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1454  BOOL  RD_BOOL
1455  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1456              char *command, char *directory)              char *command, char *directory)
1457  {  {
# Line 1411  rdp_connect(char *server, uint32 flags, Line 1463  rdp_connect(char *server, uint32 flags,
1463  }  }
1464    
1465  /* Establish a reconnection up to the RDP layer */  /* Establish a reconnection up to the RDP layer */
1466  BOOL  RD_BOOL
1467  rdp_reconnect(char *server, uint32 flags, char *domain, char *password,  rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1468                char *command, char *directory, char *cookie)                char *command, char *directory, char *cookie)
1469  {  {

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

  ViewVC Help
Powered by ViewVC 1.1.26