/[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 33 by matty, Sat Sep 15 12:34:34 2001 UTC revision 220 by matthewc, Thu Oct 10 07:25:31 2002 UTC
# Line 1  Line 1 
1  /*  /*
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-2002
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 */
26    #include <termios.h>            /* tcgetattr tcsetattr */
27  #include <sys/stat.h>           /* stat */  #include <sys/stat.h>           /* stat */
28  #include <sys/time.h>           /* gettimeofday */  #include <sys/time.h>           /* gettimeofday */
29  #include <sys/times.h>          /* times */  #include <sys/times.h>          /* times */
30  #include "rdesktop.h"  #include "rdesktop.h"
31    
32    #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 title[32] = "";
44  char username[16];  char username[16];
45  char hostname[16];  char hostname[16];
46  int width;  char keymapname[16];
47  int height;  int keylayout = 0x409;          /* Defaults to US keyboard layout */
48  int keylayout = 0x409;  int width = 800;
49    int height = 600;
50    int tcp_port_rdp = TCP_PORT_RDP;
51  BOOL bitmap_compression = True;  BOOL bitmap_compression = True;
52  BOOL sendmotion = True;  BOOL sendmotion = True;
53  BOOL orders = True;  BOOL orders = True;
 BOOL licence = True;  
54  BOOL encryption = True;  BOOL encryption = True;
55  BOOL desktop_save = True;  BOOL desktop_save = True;
56  BOOL fullscreen = False;  BOOL fullscreen = False;
57    BOOL grab_keyboard = True;
58    
59  /* Display usage information */  /* Display usage information */
60  static void  static void
61  usage(char *program)  usage(char *program)
62  {  {
63          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
64          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
65          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
66          printf("   -s: shell\n");  
67          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server\n", program);
68          printf("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
69          printf("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
70          printf("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -s: shell\n");
71          printf("   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -c: working directory\n");
72          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
73          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
74          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");
75          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
76          printf("   -l: do not request licence\n\n");          fprintf(stderr, "   -f: full-screen mode\n");
77            fprintf(stderr, "   -b: force bitmap updates\n");
78            fprintf(stderr, "   -e: disable encryption (French TS)\n");
79            fprintf(stderr, "   -m: do not send motion events\n");
80            fprintf(stderr, "   -t: rdp tcp port\n");
81            fprintf(stderr, "   -K: keep window manager key bindings\n");
82            fprintf(stderr, "   -w: window title\n");
83    }
84    
85    static BOOL
86    read_password(char *password, int size)
87    {
88            struct termios tios;
89            BOOL ret = False;
90            int istty = 0;
91            char *p;
92    
93            if (tcgetattr(STDIN_FILENO, &tios) == 0)
94            {
95                    fprintf(stderr, "Password: ");
96                    tios.c_lflag &= ~ECHO;
97                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
98                    istty = 1;
99            }
100    
101            if (fgets(password, size, stdin) != NULL)
102            {
103                    ret = True;
104    
105                    /* strip final newline */
106                    p = strchr(password, '\n');
107                    if (p != NULL)
108                            *p = 0;
109            }
110    
111            if (istty)
112            {
113                    tios.c_lflag |= ECHO;
114                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
115                    fprintf(stderr, "\n");
116            }
117    
118            return ret;
119  }  }
120    
121  /* Client program */  /* Client program */
# Line 70  main(int argc, char *argv[]) Line 127  main(int argc, char *argv[])
127          char password[16];          char password[16];
128          char shell[32];          char shell[32];
129          char directory[32];          char directory[32];
130          char title[32];          BOOL prompt_password;
131          struct passwd *pw;          struct passwd *pw;
132          char *server, *p;          char *server, *p;
133          uint32 flags;          uint32 flags;
134          int c;          int c;
135    
         printf("rdesktop: A Remote Desktop Protocol client.\n");  
         printf("Version " VERSION ". Copyright (C) 1999-2001 Matt Chapman.\n");  
         printf("See http://www.rdesktop.org/ for more information.\n\n");  
   
136          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
137            prompt_password = False;
138          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
139            strcpy(keymapname, "us");
140    
141          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemlh?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemKw:h?")) != -1)
142          {          {
143                  switch (c)                  switch (c)
144                  {                  {
# Line 104  main(int argc, char *argv[]) Line 159  main(int argc, char *argv[])
159                                  break;                                  break;
160    
161                          case 'p':                          case 'p':
162                                    if ((optarg[0] == '-') && (optarg[1] == 0))
163                                    {
164                                            prompt_password = True;
165                                            break;
166                                    }
167    
168                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
169                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
170    
171                                    /* try to overwrite argument so it won't appear in ps */
172                                    p = optarg;
173                                    while (*p)
174                                            *(p++) = 'X';
175                                  break;                                  break;
176    
177                          case 'n':                          case 'n':
# Line 113  main(int argc, char *argv[]) Line 179  main(int argc, char *argv[])
179                                  break;                                  break;
180    
181                          case 'k':                          case 'k':
182                                  keylayout = strtol(optarg, NULL, 16);                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                 if (keylayout == 0)  
                                 {  
                                         error("invalid keyboard layout\n");  
                                         return 1;  
                                 }  
183                                  break;                                  break;
184    
185                          case 'g':                          case 'g':
186                                  width = strtol(optarg, &p, 10);                                  width = strtol(optarg, &p, 10);
187                                  if (*p == 'x')                                  if (*p == 'x')
188                                          height = strtol(p+1, NULL, 10);                                          height = strtol(p + 1, NULL, 10);
189    
190                                  if ((width == 0) || (height == 0))                                  if ((width == 0) || (height == 0))
191                                  {                                  {
# Line 149  main(int argc, char *argv[]) Line 210  main(int argc, char *argv[])
210                                  sendmotion = False;                                  sendmotion = False;
211                                  break;                                  break;
212    
213                          case 'l':                          case 't':
214                                  licence = False;                                  tcp_port_rdp = strtol(optarg, NULL, 10);
215                                    break;
216    
217                            case 'K':
218                                    grab_keyboard = False;
219                                    break;
220    
221                            case 'w':
222                                    strncpy(title, optarg, sizeof(title));
223                                  break;                                  break;
224    
225                          case 'h':                          case 'h':
# Line 196  main(int argc, char *argv[]) Line 265  main(int argc, char *argv[])
265                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
266          }          }
267    
268          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
269          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
270    
271          if ((width == 0) || (height == 0))          if (title[0] == 0)
272          {          {
273                  width = 800;                  strcpy(title, "rdesktop - ");
274                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
275          }          }
276    
277          strcpy(title, "rdesktop - ");          if (!ui_init())
278          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
279    
280          if (ui_create_window(title))          if (!rdp_connect(server, flags, domain, password, shell, directory))
281          {                  return 1;
282                  if (!rdp_connect(server, flags, domain, password, shell,  
283                                   directory))          DEBUG(("Connection successful.\n"));
284                          return 1;          memset(password, 0, sizeof(password));
285    
286                  printf("Connection successful.\n");          if (ui_create_window())
287            {
288                  rdp_main_loop();                  rdp_main_loop();
                 printf("Disconnecting...\n");  
289                  ui_destroy_window();                  ui_destroy_window();
290          }          }
291    
292            DEBUG(("Disconnecting...\n"));
293          rdp_disconnect();          rdp_disconnect();
294            ui_deinit();
295          return 0;          return 0;
296  }  }
297    
298    #ifdef EGD_SOCKET
299    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
300    static BOOL
301    generate_random_egd(uint8 * buf)
302    {
303            struct sockaddr_un addr;
304            BOOL ret = False;
305            int fd;
306    
307            fd = socket(AF_UNIX, SOCK_STREAM, 0);
308            if (fd == -1)
309                    return False;
310    
311            addr.sun_family = AF_UNIX;
312            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
313            if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
314                    goto err;
315    
316            /* PRNGD and EGD use a simple communications protocol */
317            buf[0] = 1;  /* Non-blocking (similar to /dev/urandom) */
318            buf[1] = 32; /* Number of requested random bytes */
319            if (write(fd, buf, 2) != 2)
320                    goto err;
321    
322            if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
323                    goto err;
324    
325            if (read(fd, buf, 32) != 32)
326                    goto err;
327    
328            ret = True;
329    
330    err:
331            close(fd);
332            return ret;
333    }
334    #endif
335    
336  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
337  void  void
338  generate_random(uint8 *random)  generate_random(uint8 * random)
339  {  {
340          struct stat st;          struct stat st;
341          struct tms tmsbuf;          struct tms tmsbuf;
342          uint32 *r = (uint32 *) random;          MD5_CTX md5;
343          int fd;          uint32 *r;
344            int fd, n;
345    
346          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
347          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
348              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
349          {          {
350                  read(fd, random, 32);                  n = read(fd, random, 32);
351                  close(fd);                  close(fd);
352                  return;                  if (n == 32)
353                            return;
354          }          }
355    
356    #ifdef EGD_SOCKET
357            /* As a second preference use an EGD */
358            if (generate_random_egd(random))
359                    return;
360    #endif
361    
362          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
363            r = (uint32 *)random;
364          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
365          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
366          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 259  generate_random(uint8 *random) Line 369  generate_random(uint8 *random)
369          r[5] = st.st_atime;          r[5] = st.st_atime;
370          r[6] = st.st_mtime;          r[6] = st.st_mtime;
371          r[7] = st.st_ctime;          r[7] = st.st_ctime;
372    
373            /* Hash both halves with MD5 to obscure possible patterns */
374            MD5_Init(&md5);
375            MD5_Update(&md5, random, 16);
376            MD5_Final(random, &md5);
377            MD5_Update(&md5, random+16, 16);
378            MD5_Final(random+16, &md5);
379  }  }
380    
381  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 339  hexdump(unsigned char *p, unsigned int l Line 456  hexdump(unsigned char *p, unsigned int l
456                          printf("%02x ", line[i]);                          printf("%02x ", line[i]);
457    
458                  for (; i < 16; i++)                  for (; i < 16; i++)
459                                  printf("   ");                          printf("   ");
460    
461                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
462                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
463    
464                  printf("\n");                  printf("\n");
465                  offset += thisline;                  offset += thisline;
466                  line += thisline;                  line += thisline;
467          }          }
468  }  }
469    
470    #ifdef SAVE_LICENCE
471    int
472    load_licence(unsigned char **data)
473    {
474            char path[PATH_MAX];
475            char *home;
476            struct stat st;
477            int fd;
478    
479            home = getenv("HOME");
480            if (home == NULL)
481                    return -1;
482    
483            STRNCPY(path, home, sizeof(path));
484            strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);
485    
486            fd = open(path, O_RDONLY);
487            if (fd == -1)
488                    return -1;
489    
490            if (fstat(fd, &st))
491                    return -1;
492    
493            *data = xmalloc(st.st_size);
494            return read(fd, *data, st.st_size);
495    }
496    
497    void
498    save_licence(unsigned char *data, int length)
499    {
500            char path[PATH_MAX];
501            char *home;
502            int fd;
503    
504            home = getenv("HOME");
505            if (home == NULL)
506                    return;
507    
508            STRNCPY(path, home, sizeof(path));
509            strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);
510            mkdir(path, 0700);
511    
512            strncat(path, "/licence", sizeof(path) - strlen(path) - 1);
513    
514            fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
515            if (fd == -1)
516            {
517                    perror("open");
518                    return;
519            }
520    
521            write(fd, data, length);
522            close(fd);
523    }
524    #endif

Legend:
Removed from v.33  
changed lines
  Added in v.220

  ViewVC Help
Powered by ViewVC 1.1.26