/[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 713 by jsorg71, Wed Jun 16 03:08:55 2004 UTC revision 977 by astrand, Mon Aug 8 19:15:57 2005 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-2002     Copyright (C) Matthew Chapman 1999-2005
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    #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;
# Line 34  extern int g_server_bpp; Line 48  extern int g_server_bpp;
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;
51    extern BOOL g_bitmap_cache_persist_enable;
52    
53  uint8 *g_next_packet;  uint8 *g_next_packet;
54  uint32 g_rdp_shareid;  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)
79  {  {
80          static STREAM rdp_s;          static STREAM rdp_s;
81          uint16 length, pdu_type;          uint16 length, pdu_type;
82            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();                  rdp_s = sec_recv(&rdpver);
87                  if (rdp_s == NULL)                  if (rdp_s == NULL)
88                          return NULL;                          return NULL;
89                    if (rdpver == 0xff)
90                    {
91                            g_next_packet = rdp_s->end;
92                            *type = 0;
93                            return rdp_s;
94                    }
95                    else if (rdpver != 3)
96                    {
97                            /* rdp5_process should move g_next_packet ok */
98                            rdp5_process(rdp_s);
99                            *type = 0;
100                            return rdp_s;
101                    }
102    
103                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
104          }          }
# Line 125  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 145  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          return i - 1;                  while (i < uni_len / 2)
285                    {
286                            in_uint8a(s, &string[i++], 1);
287                            in_uint8s(s, 1);
288                    }
289    
290                    return i - 1;
291            }
292  }  }
293    
294    
# Line 176  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 366  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    /* 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
531    rdp_enum_bmpcache2(void)
532    {
533            STREAM s;
534            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
535            uint32 num_keys, offset, count, flags;
536    
537            offset = 0;
538            num_keys = pstcache_enumerate(2, keylist);
539    
540            while (offset < num_keys)
541            {
542                    count = MIN(num_keys - offset, 169);
543    
544                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
545    
546                    flags = 0;
547                    if (offset == 0)
548                            flags |= PDU_FLAG_FIRST;
549                    if (num_keys - offset <= 169)
550                            flags |= PDU_FLAG_LAST;
551    
552                    /* header */
553                    out_uint32_le(s, 0);
554                    out_uint16_le(s, count);
555                    out_uint16_le(s, 0);
556                    out_uint16_le(s, 0);
557                    out_uint16_le(s, 0);
558                    out_uint16_le(s, 0);
559                    out_uint16_le(s, num_keys);
560                    out_uint32_le(s, 0);
561                    out_uint32_le(s, flags);
562    
563                    /* list */
564                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
565    
566                    s_mark_end(s);
567                    rdp_send_data(s, 0x2b);
568    
569                    offset += 169;
570            }
571    }
572    
573  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
574  static void  static void
575  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 436  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 486  rdp_out_bmpcache_caps(STREAM s) Line 694  rdp_out_bmpcache_caps(STREAM s)
694          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
695  }  }
696    
697    /* Output bitmap cache v2 capability set */
698    static void
699    rdp_out_bmpcache2_caps(STREAM s)
700    {
701            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
702            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
703    
704            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
705    
706            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);
710            out_uint32_le(s, BMPCACHE2_C1_CELLS);
711            if (pstcache_init(2))
712            {
713                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
714            }
715            else
716            {
717                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
718            }
719            out_uint8s(s, 20);      /* other bitmap caches not used */
720    }
721    
722  /* Output control capability set */  /* Output control capability set */
723  static void  static void
724  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 778  rdp_out_colcache_caps(STREAM s)
778          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
779  }  }
780    
781  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
782          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
783          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
793  };  };
794    
795  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
796    
797    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
798    
799    static uint8 caps_0x10[] = {
800            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
801            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
802            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
803            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
804            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
805            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
806    };
807    
808    /* Output unknown capability sets */
809  static void  static void
810  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
811  {  {
812          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
813          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
814    
815          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
816  }  }
817    
818  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 826  rdp_send_confirm_active(void)
826                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
827                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
828                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
829                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
830                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
831                    4 /* w2k fix, why? */ ;
832    
833          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
834    
# Line 608  rdp_send_confirm_active(void) Line 848  rdp_send_confirm_active(void)
848          rdp_out_general_caps(s);          rdp_out_general_caps(s);
849          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
850          rdp_out_order_caps(s);          rdp_out_order_caps(s);
851          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
852          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
853          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
854          rdp_out_control_caps(s);          rdp_out_control_caps(s);
855          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
856          rdp_out_share_caps(s);          rdp_out_share_caps(s);
857          rdp_out_unknown_caps(s);  
858            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
859            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
860            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
861            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
862    
863          s_mark_end(s);          s_mark_end(s);
864          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 659  rdp_process_bitmap_caps(STREAM s) Line 903  rdp_process_bitmap_caps(STREAM s)
903          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
904          {          {
905                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
906                                  width, height);                          width, height);
907                  g_width = width;                  g_width = width;
908                  g_height = height;                  g_height = height;
909                  ui_resize_window();                  ui_resize_window();
910          }          }
911  }  }
912    
913  /* Respond to a demand active PDU */  /* Process server capabilities */
914  static void  static void
915  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
916  {  {
917          int n;          int n;
918          uint8 type, *next;          uint8 *next, *start;
919          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
920    
921          in_uint32_le(s, g_rdp_shareid);          start = s->p;
         in_uint16_le(s, len_src_descriptor);  
         in_uint16_le(s, len_combined_caps);  
         in_uint8s(s, len_src_descriptor);  
922    
923          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
924          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
925    
926          DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));          for (n = 0; n < ncapsets; n++)
   
         for (n = 0; n < num_capsets; n++)  
927          {          {
928                    if (s->p > start + length)
929                            return;
930    
931                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
932                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
933    
# Line 704  process_demand_active(STREAM s) Line 946  process_demand_active(STREAM s)
946    
947                  s->p = next;                  s->p = next;
948          }          }
949    }
950    
951    /* Respond to a demand active PDU */
952    static void
953    process_demand_active(STREAM s)
954    {
955            uint8 type;
956            uint16 len_src_descriptor, len_combined_caps;
957    
958            in_uint32_le(s, g_rdp_shareid);
959            in_uint16_le(s, len_src_descriptor);
960            in_uint16_le(s, len_combined_caps);
961            in_uint8s(s, len_src_descriptor);
962    
963            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
964            rdp_process_server_caps(s, len_combined_caps);
965    
966          rdp_send_confirm_active();          rdp_send_confirm_active();
967          rdp_send_synchronise();          rdp_send_synchronise();
# Line 716  process_demand_active(STREAM s) Line 974  process_demand_active(STREAM s)
974    
975          if (g_use_rdp5)          if (g_use_rdp5)
976          {          {
977                    rdp_enum_bmpcache2();
978                  rdp_send_fonts(3);                  rdp_send_fonts(3);
979          }          }
980          else          else
# Line 982  process_data_pdu(STREAM s, uint32 * ext_ Line 1241  process_data_pdu(STREAM s, uint32 * ext_
1241    
1242          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1243          {          {
1244                    if (len > RDP_MPPC_DICT_SIZE)
1245                            error("error decompressed packet size exceeds max\n");
1246                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1247                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1248    
1249                  //len -= 18;                  /* len -= 18; */
1250    
1251                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1252                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1038  process_data_pdu(STREAM s, uint32 * ext_ Line 1298  process_data_pdu(STREAM s, uint32 * ext_
1298          return False;          return False;
1299  }  }
1300    
1301  /* Process incoming packets */  /* Process redirect PDU from Session Directory */
1302  void  static BOOL
1303  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1304  {  {
1305          uint8 type;          uint32 len;
         BOOL disc = False;      /* True when a disconnect PDU was received */  
         STREAM s;  
1306    
1307          while ((s = rdp_recv(&type)) != NULL)          /* these 2 bytes are unknown, seem to be zeros */
1308          {          in_uint8s(s, 2);
                 switch (type)  
                 {  
                         case RDP_PDU_DEMAND_ACTIVE:  
                                 process_demand_active(s);  
                                 *deactivated = False;  
                                 break;  
1309    
1310                          case RDP_PDU_DEACTIVATE:          /* read connection flags */
1311                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));          in_uint32_le(s, g_redirect_flags);
                                 *deactivated = True;  
                                 break;  
1312    
1313                          case RDP_PDU_DATA:          /* read length of ip string */
1314                                  disc = process_data_pdu(s, ext_disc_reason);          in_uint32_le(s, len);
                                 break;  
1315    
1316                          case 0:          /* read ip string */
1317                                  break;          rdp_in_unistr(s, g_redirect_server, len);
1318    
1319                          default:          /* read length of cookie string */
1320                                  unimpl("PDU %d\n", type);          in_uint32_le(s, len);
                 }  
1321    
1322                  if (disc)          /* read cookie string (plain ASCII) */
1323                  {          in_uint8a(s, g_redirect_cookie, len);
1324                          return;          g_redirect_cookie[len] = 0;
1325                  }  
1326          }          /* read length of username string */
1327          return;          in_uint32_le(s, len);
1328    
1329            /* read username string */
1330            rdp_in_unistr(s, g_redirect_username, len);
1331    
1332            /* read length of domain string */
1333            in_uint32_le(s, len);
1334    
1335            /* read domain string */
1336            rdp_in_unistr(s, g_redirect_domain, len);
1337    
1338            /* read length of password string */
1339            in_uint32_le(s, len);
1340    
1341            /* read password string */
1342            rdp_in_unistr(s, g_redirect_password, len);
1343    
1344            g_redirect = True;
1345    
1346            return True;
1347    }
1348    
1349    /* Process incoming packets */
1350    /* nevers gets out of here till app is done */
1351    void
1352    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1353    {
1354            while (rdp_loop(deactivated, ext_disc_reason))
1355                    ;
1356  }  }
1357    
1358  /* used in uiports, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1359  BOOL  BOOL
1360  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1361  {  {
# Line 1088  rdp_loop(BOOL * deactivated, uint32 * ex Line 1364  rdp_loop(BOOL * deactivated, uint32 * ex
1364          BOOL cont = True;          BOOL cont = True;
1365          STREAM s;          STREAM s;
1366    
1367     while (cont)          while (cont)
1368          {          {
1369                  s = rdp_recv(&type);                  s = rdp_recv(&type);
1370                  if (s == NULL)                  if (s == NULL)
# Line 1103  rdp_loop(BOOL * deactivated, uint32 * ex Line 1379  rdp_loop(BOOL * deactivated, uint32 * ex
1379                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1380                                  *deactivated = True;                                  *deactivated = True;
1381                                  break;                                  break;
1382                            case RDP_PDU_REDIRECT:
1383                                    return process_redirect_pdu(s);
1384                                    break;
1385                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1386                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1387                                  break;                                  break;
# Line 1130  rdp_connect(char *server, uint32 flags, Line 1409  rdp_connect(char *server, uint32 flags,
1409          return True;          return True;
1410  }  }
1411    
1412    /* Establish a reconnection up to the RDP layer */
1413    BOOL
1414    rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1415                  char *command, char *directory, char *cookie)
1416    {
1417            if (!sec_reconnect(server))
1418                    return False;
1419    
1420            rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1421            return True;
1422    }
1423    
1424    /* Called during redirection to reset the state to support redirection */
1425    void
1426    rdp_reset_state(void)
1427    {
1428            g_next_packet = NULL;   /* reset the packet information */
1429            g_rdp_shareid = 0;
1430            sec_reset_state();
1431    }
1432    
1433  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1434  void  void
1435  rdp_disconnect(void)  rdp_disconnect(void)

Legend:
Removed from v.713  
changed lines
  Added in v.977

  ViewVC Help
Powered by ViewVC 1.1.26