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

Legend:
Removed from v.29  
changed lines
  Added in v.651

  ViewVC Help
Powered by ViewVC 1.1.26