/[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 29 by matty, Fri Sep 14 03:38:39 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-2000     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    
21  #include <stdlib.h>             /* malloc realloc free */  #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    char keymapname[16];
47    int keylayout = 0x409;          /* Defaults to US keyboard layout */
48  int width = 800;  int width = 800;
49  int height = 600;  int height = 600;
50  int keylayout = 0x409;  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;
54  BOOL licence = True;  BOOL encryption = True;
 BOOL use_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          STATUS("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
64          STATUS("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
65          STATUS("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
66          STATUS("   -s: shell\n");  
67          STATUS("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server\n", program);
68          STATUS("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
69          STATUS("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
70          STATUS("   -w: desktop width\n");          fprintf(stderr, "   -s: shell\n");
71          STATUS("   -h: desktop height\n");          fprintf(stderr, "   -c: working directory\n");
72          STATUS("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
73          STATUS("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
74          STATUS("   -m: do not send motion events\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");
75          STATUS("   -l: do not request licence\n\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
76            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 */
122  int  int
123  main(int argc, char *argv[])  main(int argc, char *argv[])
124  {  {
125          struct passwd *pw;          char fullhostname[64];
         char *server;  
         uint32 flags;  
126          char domain[16];          char domain[16];
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;
132            char *server, *p;
133            uint32 flags;
134          int c;          int c;
135    
         STATUS("rdesktop: A Remote Desktop Protocol client.\n");  
         STATUS("Version " VERSION  
                ". Copyright (C) 1999-2000 Matt Chapman.\n");  
         STATUS("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:g:k:mbleKFVh?")) != -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                  {                  {
145                          case 'u':                          case 'u':
146                                  strncpy(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
147                                  break;                                  break;
148    
149                          case 'd':                          case 'd':
150                                  strncpy(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
                                 break;  
   
                         case 'p':  
                                 flags |= RDP_LOGON_AUTO;  
                                 strncpy(password, optarg, sizeof(password));  
151                                  break;                                  break;
152    
153                          case 's':                          case 's':
154                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(shell, optarg, sizeof(shell));
155                                  break;                                  break;
156    
157                          case 'c':                          case 'c':
158                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(directory, optarg, sizeof(directory));
159                                  break;                                  break;
160    
161                          case 'n':                          case 'p':
162                                  strncpy(hostname, optarg, sizeof(hostname));                                  if ((optarg[0] == '-') && (optarg[1] == 0))
                                 break;  
                         case 'g':  
163                                  {                                  {
164                                          char *tgem = 0;                                          prompt_password = True;
165                                          width = strtol(optarg, NULL, 10);                                          break;
                                         tgem = strchr(optarg, 'x');  
                                         if ((tgem == 0) || (strlen(tgem) < 2))  
                                         {  
                                                 ERROR  
                                                         ("-g: invalid parameter. Syntax example: -g 1024x768\n");  
                                                 exit(1);  
                                         }  
                                         height = strtol(tgem + 1, NULL, 10);  
166                                  }                                  }
167    
168                                    STRNCPY(password, optarg, sizeof(password));
169                                    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;
176    
177                            case 'n':
178                                    STRNCPY(hostname, optarg, sizeof(hostname));
179                                  break;                                  break;
180    
181                          case 'k':                          case 'k':
182                                  keylayout = strtol(optarg, NULL, 16);                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                 /* keylayout = find_keyb_code(optarg); */  
                                 if (keylayout == 0)  
                                         return 0;  
183                                  break;                                  break;
184    
185                          case 'm':                          case 'g':
186                                  sendmotion = False;                                  width = strtol(optarg, &p, 10);
187                                    if (*p == 'x')
188                                            height = strtol(p + 1, NULL, 10);
189    
190                                    if ((width == 0) || (height == 0))
191                                    {
192                                            error("invalid geometry\n");
193                                            return 1;
194                                    }
195                                    break;
196    
197                            case 'f':
198                                    fullscreen = True;
199                                  break;                                  break;
200    
201                          case 'b':                          case 'b':
202                                  orders = False;                                  orders = False;
203                                  break;                                  break;
204    
205                          case 'l':                          case 'e':
206                                  licence = False;                                  encryption = False;
207                                  break;                                  break;
208    
209                          case 'e':                          case 'm':
210                                  use_encryption = False;                                  sendmotion = False;
211                                  break;                                  break;
212    
213                          case 'F':                          case 't':
214                                  fullscreen = True;                                  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 172  main(int argc, char *argv[]) Line 243  main(int argc, char *argv[])
243                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
244                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
245                  {                  {
246                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
247                          return 1;                          return 1;
248                  }                  }
249    
250                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(username, pw->pw_name, sizeof(username));
251          }          }
252    
253          if (hostname[0] == 0)          if (hostname[0] == 0)
254          {          {
255                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
256                  {                  {
257                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
258                          return 1;                          return 1;
259                  }                  }
260    
261                    p = strchr(fullhostname, '.');
262                    if (p != NULL)
263                            *p = 0;
264    
265                    STRNCPY(hostname, fullhostname, sizeof(hostname));
266          }          }
267    
268          strcpy(title, "rdesktop - ");          if (prompt_password && read_password(password, sizeof(password)))
269          strncat(title, server, sizeof(title));                  flags |= RDP_LOGON_AUTO;
270    
271          if (ui_create_window(title))          if (title[0] == 0)
272          {          {
273                  if (!rdp_connect(server, flags, domain, password, shell,                  strcpy(title, "rdesktop - ");
274                                   directory))                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
275                          return 1;          }
276    
277            if (!ui_init())
278                    return 1;
279    
280            if (!rdp_connect(server, flags, domain, password, shell, directory))
281                    return 1;
282    
283                  STATUS("Connection successful.\n");          DEBUG(("Connection successful.\n"));
284            memset(password, 0, sizeof(password));
285    
286            if (ui_create_window())
287            {
288                  rdp_main_loop();                  rdp_main_loop();
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          /* If we have a kernel random device, use it. */  
346          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
347            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
348                || ((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 232  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 241  xmalloc(int size) Line 385  xmalloc(int size)
385          void *mem = malloc(size);          void *mem = malloc(size);
386          if (mem == NULL)          if (mem == NULL)
387          {          {
388                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
389                  exit(1);                  exit(1);
390          }          }
391          return mem;          return mem;
# Line 254  xrealloc(void *oldmem, int size) Line 398  xrealloc(void *oldmem, int size)
398          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
399          if (mem == NULL)          if (mem == NULL)
400          {          {
401                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
402                  exit(1);                  exit(1);
403          }          }
404          return mem;          return mem;
# Line 267  xfree(void *mem) Line 411  xfree(void *mem)
411          free(mem);          free(mem);
412  }  }
413    
414  /* Produce a hex dump */  /* report an error */
415    void
416    error(char *format, ...)
417    {
418            va_list ap;
419    
420            fprintf(stderr, "ERROR: ");
421    
422            va_start(ap, format);
423            vfprintf(stderr, format, ap);
424            va_end(ap);
425    }
426    
427    /* report an unimplemented protocol feature */
428    void
429    unimpl(char *format, ...)
430    {
431            va_list ap;
432    
433            fprintf(stderr, "NOT IMPLEMENTED: ");
434    
435            va_start(ap, format);
436            vfprintf(stderr, format, ap);
437            va_end(ap);
438    }
439    
440    /* produce a hex dump */
441  void  void
442  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
443  {  {
# Line 277  hexdump(unsigned char *p, unsigned int l Line 447  hexdump(unsigned char *p, unsigned int l
447    
448          while (offset < len)          while (offset < len)
449          {          {
450                  STATUS("%04x ", offset);                  printf("%04x ", offset);
451                  thisline = len - offset;                  thisline = len - offset;
452                  if (thisline > 16)                  if (thisline > 16)
453                          thisline = 16;                          thisline = 16;
454    
455                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
456                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
457                                  STATUS("   ");  
458                    for (; i < 16; i++)
459                            printf("   ");
460    
461                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
462                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
463    
464                  STATUS("\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.29  
changed lines
  Added in v.220

  ViewVC Help
Powered by ViewVC 1.1.26