/[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 318 by astrand, Mon Feb 10 12:58:51 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
246                                        && server_bpp != 24)
247                                    {
248                                            error("invalid server bpp\n");
249                                            return 1;
250                                    }
251                                    break;
252    
253                          case 'h':                          case 'h':
254                          case '?':                          case '?':
255                          default:                          default:
# Line 179  main(int argc, char *argv[]) Line 264  main(int argc, char *argv[])
264                  return 1;                  return 1;
265          }          }
266    
267          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
268            p = strchr(server, ':');
269            if (p != NULL)
270            {
271                    tcp_port_rdp = strtol(p + 1, NULL, 10);
272                    *p = 0;
273            }
274    
275          if (username[0] == 0)          if (!username_option)
276          {          {
277                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
278                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
# Line 208  main(int argc, char *argv[]) Line 299  main(int argc, char *argv[])
299                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
300          }          }
301    
302          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
303          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
304    
305          if ((width == 0) || (height == 0))          if (title[0] == 0)
306          {          {
307                  width = 800;                  strcpy(title, "rdesktop - ");
308                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
309          }          }
310    
311          strcpy(title, "rdesktop - ");          if (!ui_init())
312          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
   
         xkeymap_init1();  
313    
314          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
315                  return 1;                  return 1;
316    
317          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
318            memset(password, 0, sizeof(password));
319    
320          if (ui_create_window(title))          if (ui_create_window())
321          {          {
322                  rdp_main_loop();                  rdp_main_loop();
323                  ui_destroy_window();                  ui_destroy_window();
324          }          }
325    
326          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
327          rdp_disconnect();          rdp_disconnect();
328            ui_deinit();
329          return 0;          return 0;
330  }  }
331    
332    #ifdef EGD_SOCKET
333    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
334    static BOOL
335    generate_random_egd(uint8 * buf)
336    {
337            struct sockaddr_un addr;
338            BOOL ret = False;
339            int fd;
340    
341            fd = socket(AF_UNIX, SOCK_STREAM, 0);
342            if (fd == -1)
343                    return False;
344    
345            addr.sun_family = AF_UNIX;
346            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
347            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
348                    goto err;
349    
350            /* PRNGD and EGD use a simple communications protocol */
351            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
352            buf[1] = 32;            /* Number of requested random bytes */
353            if (write(fd, buf, 2) != 2)
354                    goto err;
355    
356            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
357                    goto err;
358    
359            if (read(fd, buf, 32) != 32)
360                    goto err;
361    
362            ret = True;
363    
364          err:
365            close(fd);
366            return ret;
367    }
368    #endif
369    
370  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
371  void  void
372  generate_random(uint8 * random)  generate_random(uint8 * random)
373  {  {
374          struct stat st;          struct stat st;
375          struct tms tmsbuf;          struct tms tmsbuf;
376          uint32 *r = (uint32 *) random;          MD5_CTX md5;
377          int fd;          uint32 *r;
378            int fd, n;
379    
380          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
381          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
382              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
383          {          {
384                  read(fd, random, 32);                  n = read(fd, random, 32);
385                  close(fd);                  close(fd);
386                  return;                  if (n == 32)
387                            return;
388          }          }
389    
390    #ifdef EGD_SOCKET
391            /* As a second preference use an EGD */
392            if (generate_random_egd(random))
393                    return;
394    #endif
395    
396          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
397            r = (uint32 *) random;
398          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
399          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
400          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 273  generate_random(uint8 * random) Line 403  generate_random(uint8 * random)
403          r[5] = st.st_atime;          r[5] = st.st_atime;
404          r[6] = st.st_mtime;          r[6] = st.st_mtime;
405          r[7] = st.st_ctime;          r[7] = st.st_ctime;
406    
407            /* Hash both halves with MD5 to obscure possible patterns */
408            MD5_Init(&md5);
409            MD5_Update(&md5, random, 16);
410            MD5_Final(random, &md5);
411            MD5_Update(&md5, random + 16, 16);
412            MD5_Final(random + 16, &md5);
413  }  }
414    
415  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 321  error(char *format, ...) Line 458  error(char *format, ...)
458          va_end(ap);          va_end(ap);
459  }  }
460    
461    /* report a warning */
462    void
463    warning(char *format, ...)
464    {
465            va_list ap;
466    
467            fprintf(stderr, "WARNING: ");
468    
469            va_start(ap, format);
470            vfprintf(stderr, format, ap);
471            va_end(ap);
472    }
473    
474  /* report an unimplemented protocol feature */  /* report an unimplemented protocol feature */
475  void  void
476  unimpl(char *format, ...)  unimpl(char *format, ...)
# Line 356  hexdump(unsigned char *p, unsigned int l Line 506  hexdump(unsigned char *p, unsigned int l
506                          printf("   ");                          printf("   ");
507    
508                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
509                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
510    
511                  printf("\n");                  printf("\n");
512                  offset += thisline;                  offset += thisline;
513                  line += thisline;                  line += thisline;
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.318

  ViewVC Help
Powered by ViewVC 1.1.26