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

Legend:
Removed from v.64  
changed lines
  Added in v.575

  ViewVC Help
Powered by ViewVC 1.1.26