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

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

  ViewVC Help
Powered by ViewVC 1.1.26