/[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 857 by stargo, Sun Mar 13 13:36:04 2005 UTC revision 977 by astrand, Mon Aug 8 19:15:57 2005 UTC
# Line 27  Line 27 
27  #ifdef HAVE_ICONV_H  #ifdef HAVE_ICONV_H
28  #include <iconv.h>  #include <iconv.h>
29  #endif  #endif
30    
31    #ifndef ICONV_CONST
32    #define ICONV_CONST ""
33    #endif
34  #endif  #endif
35    
36  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
# Line 51  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 63  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 152  rdp_out_unistr(STREAM s, char *string, i Line 170  rdp_out_unistr(STREAM s, char *string, i
170  {  {
171  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
172          size_t ibl = strlen(string), obl = len + 2;          size_t ibl = strlen(string), obl = len + 2;
173          static iconv_t iconv_h = (iconv_t)-1;          static iconv_t iconv_h = (iconv_t) - 1;
174          char   *pin = string, *pout;          char *pin = string, *pout = (char *) s->p;
 #ifdef B_ENDIAN  
         char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need  
   
         pout = ss;  
 #else  
         pout = s->p;  
 #endif  
175    
176          memset(pout, 0, len + 4);          memset(pout, 0, len + 4);
177    
178          if (iconv_h == (iconv_t)-1)          if (g_iconv_works)
179          {          {
180                  size_t i = 1, o = 4;                  if (iconv_h == (iconv_t) - 1)
                 if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t)-1)  
181                  {                  {
182                          printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",                          size_t i = 1, o = 4;
183                                  g_codepage, WINDOWS_CODEPAGE, (int)iconv_h);                          if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
184                          return;                          {
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                  if (iconv(iconv_h, (const char**)&pin, &i, &pout, &o) == (size_t)-1)  
207                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
208                  {                  {
209                          iconv_close(iconv_h);                          iconv_close(iconv_h);
210                          iconv_h = (iconv_t)-1;                          iconv_h = (iconv_t) - 1;
211                          printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);                          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;                          return;
216                  }                  }
                 pin = string; pout = s->p;  
         }  
217    
218          if (iconv(iconv_h, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)                  s->p += len + 2;
         {  
                 iconv_close(iconv_h);  
                 iconv_h = (iconv_t)-1;  
                 printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);  
                 return;  
         }  
219    
220  #ifdef B_ENDIAN          }
221          swab(ss, s->p, len + 4);          else
222  #endif  #endif
223            {
224                    int i = 0, j = 0;
225    
226          s->p += len + 2;                  len += 2;
   
 #else /*HAVE_ICONV undef*/  
         int i = 0, j = 0;  
227    
228          len += 2;                  while (i < len)
229                    {
230                            s->p[i++] = string[j++];
231                            s->p[i++] = 0;
232                    }
233    
234          while (i < len)                  s->p += len;
         {  
                 s->p[i++] = string[j++];  
                 s->p[i++] = 0;  
235          }          }
           
         s->p += len;  
 #endif  
236  }  }
237    
238  /* Input a string in Unicode  /* Input a string in Unicode
# Line 221  rdp_in_unistr(STREAM s, char *string, in Line 244  rdp_in_unistr(STREAM s, char *string, in
244  {  {
245  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
246          size_t ibl = uni_len, obl = uni_len;          size_t ibl = uni_len, obl = uni_len;
247          char *pin, *pout = string;          char *pin = (char *) s->p, *pout = string;
248          static iconv_t iconv_h = (iconv_t)-1;          static iconv_t iconv_h = (iconv_t) - 1;
 #ifdef B_ENDIAN  
         char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need  
   
         swab(s->p, ss, uni_len);  
         pin = ss;  
 #else  
         pin = s->p;  
 #endif  
249    
250          if (iconv_h == (iconv_t)-1)          if (g_iconv_works)
251          {          {
252                  if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t)-1)                  if (iconv_h == (iconv_t) - 1)
253                  {                  {
254                          printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",                          if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
255                                  WINDOWS_CODEPAGE, g_codepage, (int)iconv_h);                          {
256                          return 0;                                  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, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)                  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
265          {                  {
266                  iconv_close(iconv_h);                          iconv_close(iconv_h);
267                  iconv_h = (iconv_t)-1;                          iconv_h = (iconv_t) - 1;
268                  printf("rdp_in_unistr: iconv fail, errno %d\n", errno);                          warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
                 return 0;  
         }  
         return pout - string;  
 #else /* HAVE_ICONV undef */  
         int i = 0;  
269    
270          while (i < uni_len / 2)                          g_iconv_works = False;
271          {                          return rdp_in_unistr(s, string, uni_len);
272                  in_uint8a(s, &string[i++], 1);                  }
                 in_uint8s(s, 1);  
         }  
273    
274          return i - 1;                  /* 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  #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;
291            }
292  }  }
293    
294    
# Line 283  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 473  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  {  {
# Line 650  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 857  rdp_process_bitmap_caps(STREAM s) Line 911  rdp_process_bitmap_caps(STREAM s)
911  }  }
912    
913  /* Process server capabilities */  /* Process server capabilities */
914  void  static void
915  rdp_process_server_caps(STREAM s, uint16 length)  rdp_process_server_caps(STREAM s, uint16 length)
916  {  {
917          int n;          int n;
# Line 1192  process_data_pdu(STREAM s, uint32 * ext_ Line 1246  process_data_pdu(STREAM s, uint32 * ext_
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 1244  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 redirect PDU from Session Directory */
1302    static BOOL
1303    process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1304    {
1305            uint32 len;
1306    
1307            /* these 2 bytes are unknown, seem to be zeros */
1308            in_uint8s(s, 2);
1309    
1310            /* read connection flags */
1311            in_uint32_le(s, g_redirect_flags);
1312    
1313            /* read length of ip string */
1314            in_uint32_le(s, len);
1315    
1316            /* read ip string */
1317            rdp_in_unistr(s, g_redirect_server, len);
1318    
1319            /* read length of cookie string */
1320            in_uint32_le(s, len);
1321    
1322            /* read cookie string (plain ASCII) */
1323            in_uint8a(s, g_redirect_cookie, len);
1324            g_redirect_cookie[len] = 0;
1325    
1326            /* read length of username string */
1327            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 */  /* Process incoming packets */
1350  /* nevers gets out of here till app is done */  /* nevers gets out of here till app is done */
1351  void  void
# Line 1277  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 1304  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.857  
changed lines
  Added in v.977

  ViewVC Help
Powered by ViewVC 1.1.26