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

Legend:
Removed from v.58  
changed lines
  Added in v.569

  ViewVC Help
Powered by ViewVC 1.1.26