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

Legend:
Removed from v.30  
changed lines
  Added in v.582

  ViewVC Help
Powered by ViewVC 1.1.26