/[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 238 by astrand, Wed Oct 23 14:55:52 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[:port]\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, "   -K: keep window manager key bindings\n");
81            fprintf(stderr, "   -T: window title\n");
82    }
83    
84    static BOOL
85    read_password(char *password, int size)
86    {
87            struct termios tios;
88            BOOL ret = False;
89            int istty = 0;
90            char *p;
91    
92            if (tcgetattr(STDIN_FILENO, &tios) == 0)
93            {
94                    fprintf(stderr, "Password: ");
95                    tios.c_lflag &= ~ECHO;
96                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
97                    istty = 1;
98            }
99    
100            if (fgets(password, size, stdin) != NULL)
101            {
102                    ret = True;
103    
104                    /* strip final newline */
105                    p = strchr(password, '\n');
106                    if (p != NULL)
107                            *p = 0;
108            }
109    
110            if (istty)
111            {
112                    tios.c_lflag |= ECHO;
113                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
114                    fprintf(stderr, "\n");
115            }
116    
117            return ret;
118  }  }
119    
120  /* Client program */  /* Client program */
121  int  int
122  main(int argc, char *argv[])  main(int argc, char *argv[])
123  {  {
124          struct passwd *pw;          char server[64];
125          char *server;          char fullhostname[64];
         uint32 flags;  
126          char domain[16];          char domain[16];
127          char password[16];          char password[16];
128          char shell[32];          char shell[128];
129          char directory[32];          char directory[32];
130          char title[32];          BOOL prompt_password;
131            struct passwd *pw;
132            uint32 flags;
133            char *p;
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:fbemKT: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 'K':
214                                  fullscreen = True;                                  grab_keyboard = False;
215                                    break;
216    
217                            case 'T':
218                                    STRNCPY(title, optarg, sizeof(title));
219                                  break;                                  break;
220    
221                          case 'h':                          case 'h':
# Line 165  main(int argc, char *argv[]) Line 232  main(int argc, char *argv[])
232                  return 1;                  return 1;
233          }          }
234    
235          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
236            p = strchr(server, ':');
237            if (p != NULL)
238            {
239                    tcp_port_rdp = strtol(p + 1, NULL, 10);
240                    *p = 0;
241            }
242    
243          if (username[0] == 0)          if (username[0] == 0)
244          {          {
245                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
246                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
247                  {                  {
248                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
249                          return 1;                          return 1;
250                  }                  }
251    
252                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(username, pw->pw_name, sizeof(username));
253          }          }
254    
255          if (hostname[0] == 0)          if (hostname[0] == 0)
256          {          {
257                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
258                  {                  {
259                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
260                          return 1;                          return 1;
261                  }                  }
262    
263                    p = strchr(fullhostname, '.');
264                    if (p != NULL)
265                            *p = 0;
266    
267                    STRNCPY(hostname, fullhostname, sizeof(hostname));
268          }          }
269    
270          strcpy(title, "rdesktop - ");          if (prompt_password && read_password(password, sizeof(password)))
271          strncat(title, server, sizeof(title));                  flags |= RDP_LOGON_AUTO;
272    
273          if (ui_create_window(title))          if (title[0] == 0)
274          {          {
275                  if (!rdp_connect(server, flags, domain, password, shell,                  strcpy(title, "rdesktop - ");
276                                   directory))                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
277                          return 1;          }
278    
279            if (!ui_init())
280                    return 1;
281    
282            if (!rdp_connect(server, flags, domain, password, shell, directory))
283                    return 1;
284    
285                  STATUS("Connection successful.\n");          DEBUG(("Connection successful.\n"));
286            memset(password, 0, sizeof(password));
287    
288            if (ui_create_window())
289            {
290                  rdp_main_loop();                  rdp_main_loop();
291                  ui_destroy_window();                  ui_destroy_window();
292          }          }
293    
294            DEBUG(("Disconnecting...\n"));
295          rdp_disconnect();          rdp_disconnect();
296            ui_deinit();
297          return 0;          return 0;
298  }  }
299    
300    #ifdef EGD_SOCKET
301    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
302    static BOOL
303    generate_random_egd(uint8 * buf)
304    {
305            struct sockaddr_un addr;
306            BOOL ret = False;
307            int fd;
308    
309            fd = socket(AF_UNIX, SOCK_STREAM, 0);
310            if (fd == -1)
311                    return False;
312    
313            addr.sun_family = AF_UNIX;
314            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
315            if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
316                    goto err;
317    
318            /* PRNGD and EGD use a simple communications protocol */
319            buf[0] = 1;  /* Non-blocking (similar to /dev/urandom) */
320            buf[1] = 32; /* Number of requested random bytes */
321            if (write(fd, buf, 2) != 2)
322                    goto err;
323    
324            if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
325                    goto err;
326    
327            if (read(fd, buf, 32) != 32)
328                    goto err;
329    
330            ret = True;
331    
332    err:
333            close(fd);
334            return ret;
335    }
336    #endif
337    
338  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
339  void  void
340  generate_random(uint8 *random)  generate_random(uint8 * random)
341  {  {
342          struct stat st;          struct stat st;
343          struct tms tmsbuf;          struct tms tmsbuf;
344          uint32 *r = (uint32 *) random;          MD5_CTX md5;
345          int fd;          uint32 *r;
346            int fd, n;
347          /* If we have a kernel random device, use it. */  
348          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
349            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
350                || ((fd = open("/dev/random", O_RDONLY)) != -1))
351          {          {
352                  read(fd, random, 32);                  n = read(fd, random, 32);
353                  close(fd);                  close(fd);
354                  return;                  if (n == 32)
355                            return;
356          }          }
357    
358    #ifdef EGD_SOCKET
359            /* As a second preference use an EGD */
360            if (generate_random_egd(random))
361                    return;
362    #endif
363    
364          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
365            r = (uint32 *)random;
366          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
367          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
368          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 232  generate_random(uint8 *random) Line 371  generate_random(uint8 *random)
371          r[5] = st.st_atime;          r[5] = st.st_atime;
372          r[6] = st.st_mtime;          r[6] = st.st_mtime;
373          r[7] = st.st_ctime;          r[7] = st.st_ctime;
374    
375            /* Hash both halves with MD5 to obscure possible patterns */
376            MD5_Init(&md5);
377            MD5_Update(&md5, random, 16);
378            MD5_Final(random, &md5);
379            MD5_Update(&md5, random+16, 16);
380            MD5_Final(random+16, &md5);
381  }  }
382    
383  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 241  xmalloc(int size) Line 387  xmalloc(int size)
387          void *mem = malloc(size);          void *mem = malloc(size);
388          if (mem == NULL)          if (mem == NULL)
389          {          {
390                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
391                  exit(1);                  exit(1);
392          }          }
393          return mem;          return mem;
# Line 254  xrealloc(void *oldmem, int size) Line 400  xrealloc(void *oldmem, int size)
400          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
401          if (mem == NULL)          if (mem == NULL)
402          {          {
403                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
404                  exit(1);                  exit(1);
405          }          }
406          return mem;          return mem;
# Line 267  xfree(void *mem) Line 413  xfree(void *mem)
413          free(mem);          free(mem);
414  }  }
415    
416  /* Produce a hex dump */  /* report an error */
417    void
418    error(char *format, ...)
419    {
420            va_list ap;
421    
422            fprintf(stderr, "ERROR: ");
423    
424            va_start(ap, format);
425            vfprintf(stderr, format, ap);
426            va_end(ap);
427    }
428    
429    /* report an unimplemented protocol feature */
430    void
431    unimpl(char *format, ...)
432    {
433            va_list ap;
434    
435            fprintf(stderr, "NOT IMPLEMENTED: ");
436    
437            va_start(ap, format);
438            vfprintf(stderr, format, ap);
439            va_end(ap);
440    }
441    
442    /* produce a hex dump */
443  void  void
444  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
445  {  {
# Line 277  hexdump(unsigned char *p, unsigned int l Line 449  hexdump(unsigned char *p, unsigned int l
449    
450          while (offset < len)          while (offset < len)
451          {          {
452                  STATUS("%04x ", offset);                  printf("%04x ", offset);
453                  thisline = len - offset;                  thisline = len - offset;
454                  if (thisline > 16)                  if (thisline > 16)
455                          thisline = 16;                          thisline = 16;
456    
457                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
458                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
459                                  STATUS("   ");  
460                    for (; i < 16; i++)
461                            printf("   ");
462    
463                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
464                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
465    
466                  STATUS("\n");                  printf("\n");
467                  offset += thisline;                  offset += thisline;
468                  line += thisline;                  line += thisline;
469          }          }
470  }  }
471    
472    #ifdef SAVE_LICENCE
473    int
474    load_licence(unsigned char **data)
475    {
476            char path[PATH_MAX];
477            char *home;
478            struct stat st;
479            int fd;
480    
481            home = getenv("HOME");
482            if (home == NULL)
483                    return -1;
484    
485            STRNCPY(path, home, sizeof(path));
486            strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);
487    
488            fd = open(path, O_RDONLY);
489            if (fd == -1)
490                    return -1;
491    
492            if (fstat(fd, &st))
493                    return -1;
494    
495            *data = xmalloc(st.st_size);
496            return read(fd, *data, st.st_size);
497    }
498    
499    void
500    save_licence(unsigned char *data, int length)
501    {
502            char path[PATH_MAX];
503            char *home;
504            int fd;
505    
506            home = getenv("HOME");
507            if (home == NULL)
508                    return;
509    
510            STRNCPY(path, home, sizeof(path));
511            strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);
512            mkdir(path, 0700);
513    
514            strncat(path, "/licence", sizeof(path) - strlen(path) - 1);
515    
516            fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
517            if (fd == -1)
518            {
519                    perror("open");
520                    return;
521            }
522    
523            write(fd, data, length);
524            close(fd);
525    }
526    #endif

Legend:
Removed from v.29  
changed lines
  Added in v.238

  ViewVC Help
Powered by ViewVC 1.1.26