/[rdesktop]/sourceforge.net/trunk/rdesktop/rdesktop.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/rdesktop.c

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

revision 79 by astrand, Mon Jul 29 20:35:13 2002 UTC revision 637 by stargo, Mon Mar 15 14:49:12 2004 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Entrypoint and utility functions     Entrypoint and utility functions
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2003
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
 #include <stdlib.h>             /* malloc realloc free */  
21  #include <stdarg.h>             /* va_list va_start va_end */  #include <stdarg.h>             /* va_list va_start va_end */
22  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
23  #include <fcntl.h>              /* open */  #include <fcntl.h>              /* open */
24  #include <pwd.h>                /* getpwuid */  #include <pwd.h>                /* getpwuid */
25  #include <limits.h>             /* PATH_MAX */  #include <termios.h>            /* tcgetattr tcsetattr */
26  #include <sys/stat.h>           /* stat */  #include <sys/stat.h>           /* stat */
27  #include <sys/time.h>           /* gettimeofday */  #include <sys/time.h>           /* gettimeofday */
28  #include <sys/times.h>          /* times */  #include <sys/times.h>          /* times */
29    #include <ctype.h>              /* toupper */
30    #include <errno.h>
31  #include "rdesktop.h"  #include "rdesktop.h"
32    
33  char username[16];  #ifdef EGD_SOCKET
34    #include <sys/socket.h>         /* socket connect */
35    #include <sys/un.h>             /* sockaddr_un */
36    #endif
37    
38    #ifdef WITH_OPENSSL
39    #include <openssl/md5.h>
40    #else
41    #include "crypto/md5.h"
42    #endif
43    
44    char g_title[64] = "";
45    char g_username[64];
46  char hostname[16];  char hostname[16];
47  char keymapname[16];  char keymapname[16];
48  int keylayout = 0x409;          /* Defaults to US keyboard layout */  int keylayout = 0x409;          /* Defaults to US keyboard layout */
 int width;  
 int height;  
 int tcp_port_rdp = TCP_PORT_RDP;  
 BOOL bitmap_compression = True;  
 BOOL sendmotion = True;  
 BOOL orders = True;  
 BOOL licence = True;  
 BOOL encryption = True;  
 BOOL desktop_save = True;  
 BOOL fullscreen = False;  
 BOOL grab_keyboard = True;  
49    
50    int g_width = 800;              /* width is special: If 0, the
51                                       geometry will be fetched from
52                                       _NET_WORKAREA. If negative,
53                                       absolute value specifies the
54                                       percent of the whole screen. */
55    int g_height = 600;
56    int tcp_port_rdp = TCP_PORT_RDP;
57    int g_server_bpp = 8;
58    int g_win_button_size = 0;      /* If zero, disable single app mode */
59    BOOL g_bitmap_compression = True;
60    BOOL g_sendmotion = True;
61    BOOL g_orders = True;
62    BOOL g_encryption = True;
63    BOOL packet_encryption = True;
64    BOOL g_desktop_save = True;
65    BOOL g_fullscreen = False;
66    BOOL g_grab_keyboard = True;
67    BOOL g_hide_decorations = False;
68    BOOL g_use_rdp5 = True;
69    BOOL g_console_session = False;
70    BOOL g_numlock_sync = False;
71    extern BOOL g_owncolmap;
72    extern BOOL g_ownbackstore;
73    extern uint32 g_embed_wnd;
74    uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
75    
76    #ifdef WITH_RDPSND
77    BOOL g_rdpsnd = False;
78    #endif
79    
80    extern RDPDR_DEVICE g_rdpdr_device[];
81    extern uint32 g_num_devices;
82    
83    #ifdef RDP2VNC
84    extern int rfb_port;
85    extern int defer_time;
86    void
87    rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password,
88                    char *shell, char *directory);
89    #endif
90  /* Display usage information */  /* Display usage information */
91  static void  static void
92  usage(char *program)  usage(char *program)
93  {  {
94          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
95          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
96          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
97          printf("   -s: shell\n");  
98          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
99          printf("   -p: password (autologon)\n");  #ifdef RDP2VNC
100          printf("   -n: client hostname\n");          fprintf(stderr, "   -V: vnc port\n");
101          printf("   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");          fprintf(stderr, "   -Q: defer time (ms)\n");
102          printf("   -g: desktop geometry (WxH)\n");  #endif
103          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -u: user name\n");
104          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -d: domain\n");
105          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -s: shell\n");
106          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -c: working directory\n");
107          printf("   -l: do not request licence\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
108          printf("   -t: rdp tcp port\n");          fprintf(stderr, "   -n: client hostname\n");
109          printf("   -K: keep window manager key bindings\n");          fprintf(stderr, "   -k: keyboard layout on server (en-us, de, sv, etc.)\n");
110            fprintf(stderr, "   -g: desktop geometry (WxH)\n");
111            fprintf(stderr, "   -f: full-screen mode\n");
112            fprintf(stderr, "   -b: force bitmap updates\n");
113            fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
114            fprintf(stderr, "   -e: disable encryption (French TS)\n");
115            fprintf(stderr, "   -E: disable encryption from client to server\n");
116            fprintf(stderr, "   -m: do not send motion events\n");
117            fprintf(stderr, "   -C: use private colour map\n");
118            fprintf(stderr, "   -D: hide window manager decorations\n");
119            fprintf(stderr, "   -K: keep window manager key bindings\n");
120            fprintf(stderr, "   -S: caption button size (single application mode)\n");
121            fprintf(stderr, "   -T: window title\n");
122            fprintf(stderr, "   -N: enable numlock syncronization\n");
123            fprintf(stderr, "   -X: embed into another window with a given id.\n");
124            fprintf(stderr, "   -a: connection colour depth\n");
125            fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex number)\n");
126            fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");
127            fprintf(stderr,
128                    "         '-r comport:COM1=/dev/ttyS0': enable serial redirection of /dev/ttyS0 to COM1\n");
129            fprintf(stderr, "             or      COM1=/dev/ttyS0,COM2=/dev/ttyS1\n");
130            fprintf(stderr,
131                    "         '-r disk:A=/mnt/floppy': enable redirection of /mnt/floppy to A:\n");
132            fprintf(stderr, "             or   A=/mnt/floppy,D=/mnt/cdrom'\n");
133            fprintf(stderr,
134                    "         '-r lptport:LPT1=/dev/lp0': enable parallel redirection of /dev/lp0 to LPT1\n");
135            fprintf(stderr, "             or      LPT1=/dev/lp0,LPT2=/dev/lp1\n");
136            fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
137            fprintf(stderr,
138                    "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
139            fprintf(stderr, "         '-r sound:[local|off|remote]': enable sound redirection\n");
140            fprintf(stderr, "                     remote would leave sound on server\n");
141            fprintf(stderr, "   -0: attach to console\n");
142            fprintf(stderr, "   -4: use RDP version 4\n");
143            fprintf(stderr, "   -5: use RDP version 5 (default)\n");
144    }
145    
146    static BOOL
147    read_password(char *password, int size)
148    {
149            struct termios tios;
150            BOOL ret = False;
151            int istty = 0;
152            char *p;
153    
154            if (tcgetattr(STDIN_FILENO, &tios) == 0)
155            {
156                    fprintf(stderr, "Password: ");
157                    tios.c_lflag &= ~ECHO;
158                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
159                    istty = 1;
160            }
161    
162            if (fgets(password, size, stdin) != NULL)
163            {
164                    ret = True;
165    
166                    /* strip final newline */
167                    p = strchr(password, '\n');
168                    if (p != NULL)
169                            *p = 0;
170            }
171    
172            if (istty)
173            {
174                    tios.c_lflag |= ECHO;
175                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
176                    fprintf(stderr, "\n");
177            }
178    
179            return ret;
180    }
181    
182    static void
183    parse_server_and_port(char *server)
184    {
185            char *p;
186    #ifdef IPv6
187            int addr_colons;
188    #endif
189    
190    #ifdef IPv6
191            p = server;
192            addr_colons = 0;
193            while (*p)
194                    if (*p++ == ':')
195                            addr_colons++;
196            if (addr_colons >= 2)
197            {
198                    /* numeric IPv6 style address format - [1:2:3::4]:port */
199                    p = strchr(server, ']');
200                    if (*server == '[' && p != NULL)
201                    {
202                            if (*(p + 1) == ':' && *(p + 2) != '\0')
203                                    tcp_port_rdp = strtol(p + 2, NULL, 10);
204                            /* remove the port number and brackets from the address */
205                            *p = '\0';
206                            strncpy(server, server + 1, strlen(server));
207                    }
208            }
209            else
210            {
211                    /* dns name or IPv4 style address format - server.example.com:port or 1.2.3.4:port */
212                    p = strchr(server, ':');
213                    if (p != NULL)
214                    {
215                            tcp_port_rdp = strtol(p + 1, NULL, 10);
216                            *p = 0;
217                    }
218            }
219    #else /* no IPv6 support */
220            p = strchr(server, ':');
221            if (p != NULL)
222            {
223                    tcp_port_rdp = strtol(p + 1, NULL, 10);
224                    *p = 0;
225            }
226    #endif /* IPv6 */
227    
228  }  }
229    
230  /* Client program */  /* Client program */
231  int  int
232  main(int argc, char *argv[])  main(int argc, char *argv[])
233  {  {
234            char server[64];
235          char fullhostname[64];          char fullhostname[64];
236          char domain[16];          char domain[16];
237          char password[16];          char password[64];
238          char shell[32];          char shell[128];
239          char directory[32];          char directory[32];
240          char title[32];          BOOL prompt_password, rdp_retval = False;
241          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
242          uint32 flags;          uint32 flags;
243            char *p;
244          int c;          int c;
245    
246          printf("rdesktop: A Remote Desktop Protocol client.\n");          int username_option = 0;
         printf("Version " VERSION  
                ". Copyright (C) 1999-2001 Matt Chapman.\n");  
         printf("See http://www.rdesktop.org/ for more information.\n\n");  
247    
248          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
249            prompt_password = False;
250          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
251          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
252            g_embed_wnd = 0;
253    
254            g_num_devices = 0;
255    
256          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlKh?")) != -1)  #ifdef RDP2VNC
257    #define VNCOPT "V:Q:"
258    #else
259    #define VNCOPT
260    #endif
261    
262            while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbBeEmCDKS:T:NX:a:x:r:045h?")) != -1)
263          {          {
264                  switch (c)                  switch (c)
265                  {                  {
266    #ifdef RDP2VNC
267                            case 'V':
268                                    rfb_port = strtol(optarg, NULL, 10);
269                                    if (rfb_port < 100)
270                                            rfb_port += 5900;
271                                    break;
272    
273                            case 'Q':
274                                    defer_time = strtol(optarg, NULL, 10);
275                                    if (defer_time < 0)
276                                            defer_time = 0;
277                                    break;
278    #endif
279    
280                          case 'u':                          case 'u':
281                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
282                                    username_option = 1;
283                                  break;                                  break;
284    
285                          case 'd':                          case 'd':
# Line 112  main(int argc, char *argv[]) Line 295  main(int argc, char *argv[])
295                                  break;                                  break;
296    
297                          case 'p':                          case 'p':
298                                    if ((optarg[0] == '-') && (optarg[1] == 0))
299                                    {
300                                            prompt_password = True;
301                                            break;
302                                    }
303    
304                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
305                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
306    
307                                    /* try to overwrite argument so it won't appear in ps */
308                                    p = optarg;
309                                    while (*p)
310                                            *(p++) = 'X';
311                                  break;                                  break;
312    
313                          case 'n':                          case 'n':
# Line 121  main(int argc, char *argv[]) Line 315  main(int argc, char *argv[])
315                                  break;                                  break;
316    
317                          case 'k':                          case 'k':
318                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
319                                  break;                                  break;
320    
321                          case 'g':                          case 'g':
322                                  width = strtol(optarg, &p, 10);                                  g_fullscreen = False;
323                                    if (!strcmp(optarg, "workarea"))
324                                    {
325                                            g_width = g_height = 0;
326                                            break;
327                                    }
328    
329                                    g_width = strtol(optarg, &p, 10);
330                                    if (g_width <= 0)
331                                    {
332                                            error("invalid geometry\n");
333                                            return 1;
334                                    }
335    
336                                  if (*p == 'x')                                  if (*p == 'x')
337                                          height = strtol(p + 1, NULL, 10);                                          g_height = strtol(p + 1, NULL, 10);
338    
339                                  if ((width == 0) || (height == 0))                                  if (g_height <= 0)
340                                  {                                  {
341                                          error("invalid geometry\n");                                          error("invalid geometry\n");
342                                          return 1;                                          return 1;
343                                  }                                  }
344    
345                                    if (*p == '%')
346                                            g_width = -g_width;
347    
348                                  break;                                  break;
349    
350                          case 'f':                          case 'f':
351                                  fullscreen = True;                                  g_fullscreen = True;
352                                  break;                                  break;
353    
354                          case 'b':                          case 'b':
355                                  orders = False;                                  g_orders = False;
356                                  break;                                  break;
357    
358                          case 'e':                          case 'B':
359                                  encryption = False;                                  g_ownbackstore = False;
360                                  break;                                  break;
361    
362                            case 'e':
363                                    g_encryption = False;
364                                    break;
365                            case 'E':
366                                    packet_encryption = False;
367                                    break;
368                          case 'm':                          case 'm':
369                                  sendmotion = False;                                  g_sendmotion = False;
370                                  break;                                  break;
371    
372                          case 'l':                          case 'C':
373                                  licence = False;                                  g_owncolmap = True;
374                                  break;                                  break;
375    
376                          case 't':                          case 'D':
377                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  g_hide_decorations = True;
378                                  break;                                  break;
379    
380                          case 'K':                          case 'K':
381                                  grab_keyboard = False;                                  g_grab_keyboard = False;
382                                    break;
383    
384                            case 'S':
385                                    if (!strcmp(optarg, "standard"))
386                                    {
387                                            g_win_button_size = 18;
388                                            break;
389                                    }
390    
391                                    g_win_button_size = strtol(optarg, &p, 10);
392    
393                                    if (*p)
394                                    {
395                                            error("invalid button size\n");
396                                            return 1;
397                                    }
398    
399                                    break;
400    
401                            case 'T':
402                                    STRNCPY(g_title, optarg, sizeof(g_title));
403                                    break;
404    
405                            case 'N':
406                                    g_numlock_sync = True;
407                                    break;
408    
409                            case 'X':
410                                    g_embed_wnd = strtol(optarg, NULL, 10);
411                                    break;
412                                    
413                            case 'a':
414                                    g_server_bpp = strtol(optarg, NULL, 10);
415                                    if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15
416                                        && g_server_bpp != 24)
417                                    {
418                                            error("invalid server bpp\n");
419                                            return 1;
420                                    }
421                                    break;
422    
423                            case 'x':
424                                    
425                                    if (strncmp("modem", optarg, 1) == 0)
426                                    {
427                                            g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
428                                    }
429                                    else if (strncmp("broadband", optarg, 1) == 0)
430                                    {
431                                            g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
432                                    }
433                                    else if (strncmp("lan", optarg, 1) == 0)
434                                    {
435                                            g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
436                                    }
437                                    else
438                                    {
439                                            g_rdp5_performanceflags = strtol(optarg, NULL, 16);
440                                    }
441                                    break;
442                                    
443                            case 'r':
444    
445                                    if (strncmp("sound", optarg, 5) == 0)
446                                    {
447                                            optarg += 5;
448    
449                                            if (*optarg == ':')
450                                            {
451                                                    *optarg++;
452                                                    while ((p = next_arg(optarg, ',')))
453                                                    {
454                                                            if (strncmp("remote", optarg, 6) == 0)
455                                                                    flags |= RDP_LOGON_LEAVE_AUDIO;
456    
457                                                            if (strncmp("local", optarg, 5) == 0)
458    #ifdef WITH_RDPSND
459                                                                    g_rdpsnd = True;
460    #else
461                                                                    warning("Not compiled with sound support");
462    #endif
463    
464                                                            if (strncmp("off", optarg, 3) == 0)
465                                                                    g_rdpsnd = False;
466    
467                                                            optarg = p;
468                                                    }
469                                            }
470                                            else
471                                            {
472    #ifdef WITH_RDPSND
473                                                    g_rdpsnd = True;
474    #else
475                                                    warning("Not compiled with sound support");
476    #endif
477                                            }
478                                    }
479                                    else if (strncmp("disk", optarg, 4) == 0)
480                                    {
481                                            /* -r disk:h:=/mnt/floppy */
482                                            disk_enum_devices(&g_num_devices, optarg + 4);
483                                    }
484                                    else if (strncmp("comport", optarg, 7) == 0)
485                                    {
486                                            serial_enum_devices(&g_num_devices, optarg + 7);
487                                    }
488                                    else if (strncmp("lptport", optarg, 7) == 0)
489                                    {
490                                            parallel_enum_devices(&g_num_devices, optarg + 7);
491                                    }
492                                    else if (strncmp("printer", optarg, 7) == 0)
493                                    {
494                                            printer_enum_devices(&g_num_devices, optarg + 7);
495                                    }
496                                    else
497                                    {
498                                            warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound\n");
499                                    }
500                                    break;
501    
502                            case '0':
503                                    g_console_session = True;
504                                    break;
505    
506                            case '4':
507                                    g_use_rdp5 = False;
508                                    break;
509    
510                            case '5':
511                                    g_use_rdp5 = True;
512                                  break;                                  break;
513    
514                          case 'h':                          case 'h':
# Line 173  main(int argc, char *argv[]) Line 519  main(int argc, char *argv[])
519                  }                  }
520          }          }
521    
522          if (argc - optind < 1)          if (argc - optind != 1)
523          {          {
524                  usage(argv[0]);                  usage(argv[0]);
525                  return 1;                  return 1;
526          }          }
527    
528          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
529            parse_server_and_port(server);
530    
531          if (username[0] == 0)          if (!username_option)
532          {          {
533                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
534                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 190  main(int argc, char *argv[]) Line 537  main(int argc, char *argv[])
537                          return 1;                          return 1;
538                  }                  }
539    
540                  STRNCPY(username, pw->pw_name, sizeof(username));                  STRNCPY(g_username, pw->pw_name, sizeof(g_username));
541          }          }
542    
543          if (hostname[0] == 0)          if (hostname[0] == 0)
# Line 208  main(int argc, char *argv[]) Line 555  main(int argc, char *argv[])
555                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
556          }          }
557    
558          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
559          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
560    
561          if ((width == 0) || (height == 0))          if (g_title[0] == 0)
562          {          {
563                  width = 800;                  strcpy(g_title, "rdesktop - ");
564                  height = 600;                  strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - "));
565          }          }
566    
567          strcpy(title, "rdesktop - ");  #ifdef RDP2VNC
568          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));          rdp2vnc_connect(server, flags, domain, password, shell, directory);
569            return 0;
570    #else
571    
572            if (!ui_init())
573                    return 1;
574    
575          xkeymap_init1();  #ifdef WITH_RDPSND
576            if (g_rdpsnd)
577                    rdpsnd_init();
578    #endif
579            rdpdr_init();
580    
581          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
582                  return 1;                  return 1;
583    
584          printf("Connection successful.\n");          /* By setting encryption to False here, we have an encrypted login
585               packet but unencrypted transfer of other packets */
586            if (!packet_encryption)
587                    g_encryption = False;
588    
589    
590            DEBUG(("Connection successful.\n"));
591            memset(password, 0, sizeof(password));
592    
593          if (ui_create_window(title))          if (ui_create_window())
594          {          {
595                  rdp_main_loop();                  rdp_retval = rdp_main_loop();
596                  ui_destroy_window();                  ui_destroy_window();
597          }          }
598    
599          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
600          rdp_disconnect();          rdp_disconnect();
601          return 0;          ui_deinit();
602    
603            if (True == rdp_retval)
604                    return 0;
605            else
606                    return 2;
607    
608    #endif
609    
610  }  }
611    
612    #ifdef EGD_SOCKET
613    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
614    static BOOL
615    generate_random_egd(uint8 * buf)
616    {
617            struct sockaddr_un addr;
618            BOOL ret = False;
619            int fd;
620    
621            fd = socket(AF_UNIX, SOCK_STREAM, 0);
622            if (fd == -1)
623                    return False;
624    
625            addr.sun_family = AF_UNIX;
626            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
627            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
628                    goto err;
629    
630            /* PRNGD and EGD use a simple communications protocol */
631            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
632            buf[1] = 32;            /* Number of requested random bytes */
633            if (write(fd, buf, 2) != 2)
634                    goto err;
635    
636            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
637                    goto err;
638    
639            if (read(fd, buf, 32) != 32)
640                    goto err;
641    
642            ret = True;
643    
644          err:
645            close(fd);
646            return ret;
647    }
648    #endif
649    
650  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
651  void  void
652  generate_random(uint8 * random)  generate_random(uint8 * random)
653  {  {
654          struct stat st;          struct stat st;
655          struct tms tmsbuf;          struct tms tmsbuf;
656          uint32 *r = (uint32 *) random;          MD5_CTX md5;
657          int fd;          uint32 *r;
658            int fd, n;
659    
660          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
661          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
662              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
663          {          {
664                  read(fd, random, 32);                  n = read(fd, random, 32);
665                  close(fd);                  close(fd);
666                  return;                  if (n == 32)
667                            return;
668          }          }
669    
670    #ifdef EGD_SOCKET
671            /* As a second preference use an EGD */
672            if (generate_random_egd(random))
673                    return;
674    #endif
675    
676          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
677            r = (uint32 *) random;
678          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
679          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
680          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 273  generate_random(uint8 * random) Line 683  generate_random(uint8 * random)
683          r[5] = st.st_atime;          r[5] = st.st_atime;
684          r[6] = st.st_mtime;          r[6] = st.st_mtime;
685          r[7] = st.st_ctime;          r[7] = st.st_ctime;
686    
687            /* Hash both halves with MD5 to obscure possible patterns */
688            MD5_Init(&md5);
689            MD5_Update(&md5, random, 16);
690            MD5_Final(random, &md5);
691            MD5_Update(&md5, random + 16, 16);
692            MD5_Final(random + 16, &md5);
693  }  }
694    
695  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 321  error(char *format, ...) Line 738  error(char *format, ...)
738          va_end(ap);          va_end(ap);
739  }  }
740    
741    /* report a warning */
742    void
743    warning(char *format, ...)
744    {
745            va_list ap;
746    
747            fprintf(stderr, "WARNING: ");
748    
749            va_start(ap, format);
750            vfprintf(stderr, format, ap);
751            va_end(ap);
752    }
753    
754  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
755  void  void
756  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 339  void Line 769  void
769  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
770  {  {
771          unsigned char *line = p;          unsigned char *line = p;
772          unsigned int thisline, offset = 0;          int i, thisline, offset = 0;
         int i;  
773    
774          while (offset < len)          while (offset < len)
775          {          {
# Line 356  hexdump(unsigned char *p, unsigned int l Line 785  hexdump(unsigned char *p, unsigned int l
785                          printf("   ");                          printf("   ");
786    
787                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
788                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
789    
790                  printf("\n");                  printf("\n");
791                  offset += thisline;                  offset += thisline;
# Line 366  hexdump(unsigned char *p, unsigned int l Line 793  hexdump(unsigned char *p, unsigned int l
793          }          }
794  }  }
795    
796    /*
797      input: src is the string we look in for needle.
798             Needle may be escaped by a backslash, in
799             that case we ignore that particular needle.
800      return value: returns next src pointer, for
801            succesive executions, like in a while loop
802            if retval is 0, then there are no more args.
803      pitfalls:
804            src is modified. 0x00 chars are inserted to
805            terminate strings.
806            return val, points on the next val chr after ins
807            0x00
808    
809            example usage:
810            while( (pos = next_arg( optarg, ',')) ){
811                    printf("%s\n",optarg);
812                    optarg=pos;
813            }
814    
815    */
816    char *
817    next_arg(char *src, char needle)
818    {
819            char *nextval;
820            char *p;
821            char *mvp = 0;
822    
823            /* EOS */
824            if (*src == (char) 0x00)
825                    return 0;
826    
827            p = src;
828            /*  skip escaped needles */
829            while ((nextval = strchr(p, needle)))
830            {
831                    mvp = nextval - 1;
832                    /* found backslashed needle */
833                    if (*mvp == '\\' && (mvp > src))
834                    {
835                            /* move string one to the left */
836                            while (*(mvp + 1) != (char) 0x00)
837                            {
838                                    *mvp = *(mvp + 1);
839                                    *mvp++;
840                            }
841                            *mvp = (char) 0x00;
842                            p = nextval;
843                    }
844                    else
845                    {
846                            p = nextval + 1;
847                            break;
848                    }
849    
850            }
851    
852            /* more args available */
853            if (nextval)
854            {
855                    *nextval = (char) 0x00;
856                    return ++nextval;
857            }
858    
859            /* no more args after this, jump to EOS */
860            nextval = src + strlen(src);
861            return nextval;
862    }
863    
864    
865    void
866    toupper_str(char *p)
867    {
868            while (*p)
869            {
870                    if ((*p >= 'a') && (*p <= 'z'))
871                            *p = toupper((int) *p);
872                    p++;
873            }
874    }
875    
876    
877    /* not all clibs got ltoa */
878    #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
879    
880    char *
881    l_to_a(long N, int base)
882    {
883            static char ret[LTOA_BUFSIZE];
884    
885            char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf);
886    
887            register int divrem;
888    
889            if (base < 36 || 2 > base)
890                    base = 10;
891    
892            if (N < 0)
893            {
894                    *head++ = '-';
895                    N = -N;
896            }
897    
898            tail = buf + sizeof(buf);
899            *--tail = 0;
900    
901            do
902            {
903                    divrem = N % base;
904                    *--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10;
905                    N /= base;
906            }
907            while (N);
908    
909            strcpy(head, tail);
910            return ret;
911    }
912    
913    
914  int  int
915  load_licence(unsigned char **data)  load_licence(unsigned char **data)
916  {  {
917          char path[PATH_MAX];          char *home, *path;
         char *home;  
918          struct stat st;          struct stat st;
919          int fd;          int fd, length;
920    
921          home = getenv("HOME");          home = getenv("HOME");
922          if (home == NULL)          if (home == NULL)
923                  return -1;                  return -1;
924    
925          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
926          strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
927    
928          fd = open(path, O_RDONLY);          fd = open(path, O_RDONLY);
929          if (fd == -1)          if (fd == -1)
# Line 388  load_licence(unsigned char **data) Line 932  load_licence(unsigned char **data)
932          if (fstat(fd, &st))          if (fstat(fd, &st))
933                  return -1;                  return -1;
934    
935          *data = xmalloc(st.st_size);          *data = (uint8 *) xmalloc(st.st_size);
936          return read(fd, *data, st.st_size);          length = read(fd, *data, st.st_size);
937            close(fd);
938            xfree(path);
939            return length;
940  }  }
941    
942  void  void
943  save_licence(unsigned char *data, int length)  save_licence(unsigned char *data, int length)
944  {  {
945          char path[PATH_MAX];          char *home, *path, *tmppath;
         char *home;  
946          int fd;          int fd;
947    
948          home = getenv("HOME");          home = getenv("HOME");
949          if (home == NULL)          if (home == NULL)
950                  return;                  return;
951    
952          STRNCPY(path, home, sizeof(path));          path = (char *) xmalloc(strlen(home) + strlen(hostname) + sizeof("/.rdesktop/licence."));
953          strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);  
954          mkdir(path, 0700);          sprintf(path, "%s/.rdesktop", home);
955            if ((mkdir(path, 0700) == -1) && errno != EEXIST)
956            {
957                    perror(path);
958                    return;
959            }
960    
961            /* write licence to licence.hostname.new, then atomically rename to licence.hostname */
962    
963          strncat(path, "/licence", sizeof(path) - strlen(path) - 1);          sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
964            tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
965            strcpy(tmppath, path);
966            strcat(tmppath, ".new");
967    
968          fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);          fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
969          if (fd == -1)          if (fd == -1)
970          {          {
971                  perror("open");                  perror(tmppath);
972                  return;                  return;
973          }          }
974    
975          write(fd, data, length);          if (write(fd, data, length) != length)
976            {
977                    perror(tmppath);
978                    unlink(tmppath);
979            }
980            else if (rename(tmppath, path) == -1)
981            {
982                    perror(path);
983                    unlink(tmppath);
984            }
985    
986          close(fd);          close(fd);
987            xfree(tmppath);
988            xfree(path);
989  }  }

Legend:
Removed from v.79  
changed lines
  Added in v.637

  ViewVC Help
Powered by ViewVC 1.1.26