/[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 79 by astrand, Mon Jul 29 20:35:13 2002 UTC revision 317 by astrand, Mon Feb 10 12:56:34 2003 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-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 "rdesktop.h"  #include "rdesktop.h"
30    
31    #ifdef EGD_SOCKET
32    #include <sys/socket.h>         /* socket connect */
33    #include <sys/un.h>             /* sockaddr_un */
34    #endif
35    
36    #ifdef WITH_OPENSSL
37    #include <openssl/md5.h>
38    #else
39    #include "crypto/md5.h"
40    #endif
41    
42    char title[32] = "";
43  char username[16];  char username[16];
44  char hostname[16];  char hostname[16];
45  char keymapname[16];  char keymapname[16];
46  int keylayout = 0x409;          /* Defaults to US keyboard layout */  int keylayout = 0x409;          /* Defaults to US keyboard layout */
47  int width;  int width = 800;                /* If width or height are reset to zero, the geometry will
48  int height;                                     be fetched from _NET_WORKAREA */
49    int height = 600;
50  int tcp_port_rdp = TCP_PORT_RDP;  int tcp_port_rdp = TCP_PORT_RDP;
51    int server_bpp = 8;
52  BOOL bitmap_compression = True;  BOOL bitmap_compression = True;
53  BOOL sendmotion = True;  BOOL sendmotion = True;
54  BOOL orders = True;  BOOL orders = True;
 BOOL licence = True;  
55  BOOL encryption = True;  BOOL encryption = True;
56  BOOL desktop_save = True;  BOOL desktop_save = True;
57  BOOL fullscreen = False;  BOOL fullscreen = False;
58  BOOL grab_keyboard = True;  BOOL grab_keyboard = True;
59    BOOL hide_decorations = False;
60    extern BOOL owncolmap;
61    
62  /* Display usage information */  /* Display usage information */
63  static void  static void
64  usage(char *program)  usage(char *program)
65  {  {
66          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
67          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2003 Matt Chapman.\n");
68          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
69          printf("   -s: shell\n");  
70          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
71          printf("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
72          printf("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
73          printf("   -k: keyboard layout on terminal server (us,sv,gr etc.)\n");          fprintf(stderr, "   -s: shell\n");
74          printf("   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -c: working directory\n");
75          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
76          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
77          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
78          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
79          printf("   -l: do not request licence\n");          fprintf(stderr, "   -f: full-screen mode\n");
80          printf("   -t: rdp tcp port\n");          fprintf(stderr, "   -b: force bitmap updates\n");
81          printf("   -K: keep window manager key bindings\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
82            fprintf(stderr, "   -m: do not send motion events\n");
83            fprintf(stderr, "   -C: use private colour map\n");
84            fprintf(stderr, "   -K: keep window manager key bindings\n");
85            fprintf(stderr, "   -T: window title\n");
86            fprintf(stderr, "   -D: hide window manager decorations\n");
87            fprintf(stderr, "   -a: server bpp\n");
88    }
89    
90    static BOOL
91    read_password(char *password, int size)
92    {
93            struct termios tios;
94            BOOL ret = False;
95            int istty = 0;
96            char *p;
97    
98            if (tcgetattr(STDIN_FILENO, &tios) == 0)
99            {
100                    fprintf(stderr, "Password: ");
101                    tios.c_lflag &= ~ECHO;
102                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
103                    istty = 1;
104            }
105    
106            if (fgets(password, size, stdin) != NULL)
107            {
108                    ret = True;
109    
110                    /* strip final newline */
111                    p = strchr(password, '\n');
112                    if (p != NULL)
113                            *p = 0;
114            }
115    
116            if (istty)
117            {
118                    tios.c_lflag |= ECHO;
119                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
120                    fprintf(stderr, "\n");
121            }
122    
123            return ret;
124  }  }
125    
126  /* Client program */  /* Client program */
127  int  int
128  main(int argc, char *argv[])  main(int argc, char *argv[])
129  {  {
130            char server[64];
131          char fullhostname[64];          char fullhostname[64];
132          char domain[16];          char domain[16];
133          char password[16];          char password[16];
134          char shell[32];          char shell[128];
135          char directory[32];          char directory[32];
136          char title[32];          BOOL prompt_password;
137          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
138          uint32 flags;          uint32 flags;
139            char *p;
140          int c;          int c;
141            int username_option = 0;
         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");  
142    
143          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
144            prompt_password = False;
145          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
146          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
147    
148          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlKh?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:a:fbemCKT:Dh?")) != -1)
149          {          {
150                  switch (c)                  switch (c)
151                  {                  {
152                          case 'u':                          case 'u':
153                                  STRNCPY(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
154                                    username_option = 1;
155                                  break;                                  break;
156    
157                          case 'd':                          case 'd':
# Line 112  main(int argc, char *argv[]) Line 167  main(int argc, char *argv[])
167                                  break;                                  break;
168    
169                          case 'p':                          case 'p':
170                                    if ((optarg[0] == '-') && (optarg[1] == 0))
171                                    {
172                                            prompt_password = True;
173                                            break;
174                                    }
175    
176                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
177                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
178    
179                                    /* try to overwrite argument so it won't appear in ps */
180                                    p = optarg;
181                                    while (*p)
182                                            *(p++) = 'X';
183                                  break;                                  break;
184    
185                          case 'n':                          case 'n':
# Line 121  main(int argc, char *argv[]) Line 187  main(int argc, char *argv[])
187                                  break;                                  break;
188    
189                          case 'k':                          case 'k':
190                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
191                                  break;                                  break;
192    
193                          case 'g':                          case 'g':
194                                    if (!strcmp(optarg, "workarea"))
195                                    {
196                                            width = height = 0;
197                                            break;
198                                    }
199    
200                                  width = strtol(optarg, &p, 10);                                  width = strtol(optarg, &p, 10);
201                                  if (*p == 'x')                                  if (*p == 'x')
202                                          height = strtol(p + 1, NULL, 10);                                          height = strtol(p + 1, NULL, 10);
# Line 153  main(int argc, char *argv[]) Line 224  main(int argc, char *argv[])
224                                  sendmotion = False;                                  sendmotion = False;
225                                  break;                                  break;
226    
227                          case 'l':                          case 'C':
228                                  licence = False;                                  owncolmap = True;
                                 break;  
   
                         case 't':  
                                 tcp_port_rdp = strtol(optarg, NULL, 10);  
229                                  break;                                  break;
230    
231                          case 'K':                          case 'K':
232                                  grab_keyboard = False;                                  grab_keyboard = False;
233                                  break;                                  break;
234    
235                            case 'T':
236                                    STRNCPY(title, optarg, sizeof(title));
237                                    break;
238    
239                            case 'D':
240                                    hide_decorations = True;
241                                    break;
242    
243                            case 'a':
244                                    server_bpp = strtol(optarg, NULL, 10);
245                                    if (server_bpp != 8 && server_bpp != 16 && server_bpp != 15 && server_bpp != 24)
246                                    {
247                                            error("invalid server bpp\n");
248                                            return 1;
249                                    }
250                                    break;
251    
252                          case 'h':                          case 'h':
253                          case '?':                          case '?':
254                          default:                          default:
# Line 179  main(int argc, char *argv[]) Line 263  main(int argc, char *argv[])
263                  return 1;                  return 1;
264          }          }
265    
266          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
267            p = strchr(server, ':');
268            if (p != NULL)
269            {
270                    tcp_port_rdp = strtol(p + 1, NULL, 10);
271                    *p = 0;
272            }
273    
274          if (username[0] == 0)          if (!username_option)
275          {          {
276                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
277                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 208  main(int argc, char *argv[]) Line 298  main(int argc, char *argv[])
298                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
299          }          }
300    
301          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
302          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
303    
304          if ((width == 0) || (height == 0))          if (title[0] == 0)
305          {          {
306                  width = 800;                  strcpy(title, "rdesktop - ");
307                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
308          }          }
309    
310          strcpy(title, "rdesktop - ");          if (!ui_init())
311          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
   
         xkeymap_init1();  
312    
313          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
314                  return 1;                  return 1;
315    
316          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
317            memset(password, 0, sizeof(password));
318    
319          if (ui_create_window(title))          if (ui_create_window())
320          {          {
321                  rdp_main_loop();                  rdp_main_loop();
322                  ui_destroy_window();                  ui_destroy_window();
323          }          }
324    
325          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
326          rdp_disconnect();          rdp_disconnect();
327            ui_deinit();
328          return 0;          return 0;
329  }  }
330    
331    #ifdef EGD_SOCKET
332    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
333    static BOOL
334    generate_random_egd(uint8 * buf)
335    {
336            struct sockaddr_un addr;
337            BOOL ret = False;
338            int fd;
339    
340            fd = socket(AF_UNIX, SOCK_STREAM, 0);
341            if (fd == -1)
342                    return False;
343    
344            addr.sun_family = AF_UNIX;
345            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
346            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
347                    goto err;
348    
349            /* PRNGD and EGD use a simple communications protocol */
350            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
351            buf[1] = 32;            /* Number of requested random bytes */
352            if (write(fd, buf, 2) != 2)
353                    goto err;
354    
355            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
356                    goto err;
357    
358            if (read(fd, buf, 32) != 32)
359                    goto err;
360    
361            ret = True;
362    
363          err:
364            close(fd);
365            return ret;
366    }
367    #endif
368    
369  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
370  void  void
371  generate_random(uint8 * random)  generate_random(uint8 * random)
372  {  {
373          struct stat st;          struct stat st;
374          struct tms tmsbuf;          struct tms tmsbuf;
375          uint32 *r = (uint32 *) random;          MD5_CTX md5;
376          int fd;          uint32 *r;
377            int fd, n;
378    
379          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
380          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
381              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
382          {          {
383                  read(fd, random, 32);                  n = read(fd, random, 32);
384                  close(fd);                  close(fd);
385                  return;                  if (n == 32)
386                            return;
387          }          }
388    
389    #ifdef EGD_SOCKET
390            /* As a second preference use an EGD */
391            if (generate_random_egd(random))
392                    return;
393    #endif
394    
395          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
396            r = (uint32 *) random;
397          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
398          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
399          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 273  generate_random(uint8 * random) Line 402  generate_random(uint8 * random)
402          r[5] = st.st_atime;          r[5] = st.st_atime;
403          r[6] = st.st_mtime;          r[6] = st.st_mtime;
404          r[7] = st.st_ctime;          r[7] = st.st_ctime;
405    
406            /* Hash both halves with MD5 to obscure possible patterns */
407            MD5_Init(&md5);
408            MD5_Update(&md5, random, 16);
409            MD5_Final(random, &md5);
410            MD5_Update(&md5, random + 16, 16);
411            MD5_Final(random + 16, &md5);
412  }  }
413    
414  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 321  error(char *format, ...) Line 457  error(char *format, ...)
457          va_end(ap);          va_end(ap);
458  }  }
459    
460    /* report a warning */
461    void
462    warning(char *format, ...)
463    {
464            va_list ap;
465    
466            fprintf(stderr, "WARNING: ");
467    
468            va_start(ap, format);
469            vfprintf(stderr, format, ap);
470            va_end(ap);
471    }
472    
473  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
474  void  void
475  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 356  hexdump(unsigned char *p, unsigned int l Line 505  hexdump(unsigned char *p, unsigned int l
505                          printf("   ");                          printf("   ");
506    
507                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
508                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
509    
510                  printf("\n");                  printf("\n");
511                  offset += thisline;                  offset += thisline;
# Line 366  hexdump(unsigned char *p, unsigned int l Line 513  hexdump(unsigned char *p, unsigned int l
513          }          }
514  }  }
515    
 int  
 load_licence(unsigned char **data)  
 {  
         char path[PATH_MAX];  
         char *home;  
         struct stat st;  
         int fd;  
   
         home = getenv("HOME");  
         if (home == NULL)  
                 return -1;  
   
         STRNCPY(path, home, sizeof(path));  
         strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);  
   
         fd = open(path, O_RDONLY);  
         if (fd == -1)  
                 return -1;  
   
         if (fstat(fd, &st))  
                 return -1;  
   
         *data = xmalloc(st.st_size);  
         return read(fd, *data, st.st_size);  
 }  
   
 void  
 save_licence(unsigned char *data, int length)  
 {  
         char path[PATH_MAX];  
         char *home;  
         int fd;  
   
         home = getenv("HOME");  
         if (home == NULL)  
                 return;  
   
         STRNCPY(path, home, sizeof(path));  
         strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);  
         mkdir(path, 0700);  
   
         strncat(path, "/licence", sizeof(path) - strlen(path) - 1);  
   
         fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);  
         if (fd == -1)  
         {  
                 perror("open");  
                 return;  
         }  
   
         write(fd, data, length);  
         close(fd);  
 }  

Legend:
Removed from v.79  
changed lines
  Added in v.317

  ViewVC Help
Powered by ViewVC 1.1.26