/[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 64 by astrand, Thu Jul 18 16:38:31 2002 UTC revision 262 by astrand, Mon Nov 18 15:37:20 2002 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Entrypoint and utility functions     Entrypoint and utility functions
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
 #include <stdlib.h>             /* malloc realloc free */  
21  #include <stdarg.h>             /* va_list va_start va_end */  #include <stdarg.h>             /* va_list va_start va_end */
22  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */  #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
23  #include <fcntl.h>              /* open */  #include <fcntl.h>              /* open */
24  #include <pwd.h>                /* getpwuid */  #include <pwd.h>                /* getpwuid */
25  #include <limits.h>             /* PATH_MAX */  #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];  char keymapname[16];
47  int keylayout;  int keylayout = 0x409;          /* Defaults to US keyboard layout */
48  int width;  int width = 800;
49  int height;  int height = 600;
50  int tcp_port_rdp = TCP_PORT_RDP;  int tcp_port_rdp = TCP_PORT_RDP;
51  BOOL bitmap_compression = True;  BOOL bitmap_compression = True;
52  BOOL sendmotion = True;  BOOL sendmotion = True;
53  BOOL orders = True;  BOOL orders = True;
 BOOL licence = True;  
54  BOOL encryption = True;  BOOL encryption = True;
55  BOOL desktop_save = True;  BOOL desktop_save = True;
56  BOOL fullscreen = False;  BOOL fullscreen = False;
57    BOOL grab_keyboard = True;
58    BOOL hide_decorations = False;
59    
60  /* Display usage information */  /* Display usage information */
61  static void  static void
62  usage(char *program)  usage(char *program)
63  {  {
64          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
65          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
66          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
67          printf("   -s: shell\n");  
68          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
69          printf("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
70          printf("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
71          printf("   -k: keyboard layout\n");          fprintf(stderr, "   -s: shell\n");
72          printf("   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -c: working directory\n");
73          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
74          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
75          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
76          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
77          printf("   -l: do not request licence\n");          fprintf(stderr, "   -f: full-screen mode\n");
78          printf("   -t: rdp tcp port\n\n");          fprintf(stderr, "   -b: force bitmap updates\n");
79            fprintf(stderr, "   -e: disable encryption (French TS)\n");
80            fprintf(stderr, "   -m: do not send motion events\n");
81            fprintf(stderr, "   -K: keep window manager key bindings\n");
82            fprintf(stderr, "   -T: window title\n");
83            fprintf(stderr, "   -D: hide window manager decorations\n");
84    }
85    
86    static BOOL
87    read_password(char *password, int size)
88    {
89            struct termios tios;
90            BOOL ret = False;
91            int istty = 0;
92            char *p;
93    
94            if (tcgetattr(STDIN_FILENO, &tios) == 0)
95            {
96                    fprintf(stderr, "Password: ");
97                    tios.c_lflag &= ~ECHO;
98                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
99                    istty = 1;
100            }
101    
102            if (fgets(password, size, stdin) != NULL)
103            {
104                    ret = True;
105    
106                    /* strip final newline */
107                    p = strchr(password, '\n');
108                    if (p != NULL)
109                            *p = 0;
110            }
111    
112            if (istty)
113            {
114                    tios.c_lflag |= ECHO;
115                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
116                    fprintf(stderr, "\n");
117            }
118    
119            return ret;
120  }  }
121    
122  /* Client program */  /* Client program */
123  int  int
124  main(int argc, char *argv[])  main(int argc, char *argv[])
125  {  {
126            char server[64];
127          char fullhostname[64];          char fullhostname[64];
128          char domain[16];          char domain[16];
129          char password[16];          char password[16];
130          char shell[32];          char shell[128];
131          char directory[32];          char directory[32];
132          char title[32];          BOOL prompt_password;
133          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
134          uint32 flags;          uint32 flags;
135            char *p;
136          int c;          int c;
137    
         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");  
   
138          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
139            prompt_password = False;
140          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
141          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
142    
143          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:t:fbemlh?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemKT:Dh?")) != -1)
144          {          {
145                  switch (c)                  switch (c)
146                  {                  {
# Line 110  main(int argc, char *argv[]) Line 161  main(int argc, char *argv[])
161                                  break;                                  break;
162    
163                          case 'p':                          case 'p':
164                                    if ((optarg[0] == '-') && (optarg[1] == 0))
165                                    {
166                                            prompt_password = True;
167                                            break;
168                                    }
169    
170                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
171                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
172    
173                                    /* try to overwrite argument so it won't appear in ps */
174                                    p = optarg;
175                                    while (*p)
176                                            *(p++) = 'X';
177                                  break;                                  break;
178    
179                          case 'n':                          case 'n':
# Line 119  main(int argc, char *argv[]) Line 181  main(int argc, char *argv[])
181                                  break;                                  break;
182    
183                          case 'k':                          case 'k':
184                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
185                                  break;                                  break;
186    
187                          case 'g':                          case 'g':
# Line 151  main(int argc, char *argv[]) Line 212  main(int argc, char *argv[])
212                                  sendmotion = False;                                  sendmotion = False;
213                                  break;                                  break;
214    
215                          case 'l':                          case 'K':
216                                  licence = False;                                  grab_keyboard = False;
217                                    break;
218    
219                            case 'T':
220                                    STRNCPY(title, optarg, sizeof(title));
221                                  break;                                  break;
222    
223                          case 't':                          case 'D':
224                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  hide_decorations = True;
225                                  break;                                  break;
226    
227                          case 'h':                          case 'h':
# Line 173  main(int argc, char *argv[]) Line 238  main(int argc, char *argv[])
238                  return 1;                  return 1;
239          }          }
240    
241          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
242            p = strchr(server, ':');
243            if (p != NULL)
244            {
245                    tcp_port_rdp = strtol(p + 1, NULL, 10);
246                    *p = 0;
247            }
248    
249          if (username[0] == 0)          if (username[0] == 0)
250          {          {
# Line 202  main(int argc, char *argv[]) Line 273  main(int argc, char *argv[])
273                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
274          }          }
275    
276          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
277          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
278    
279          if ((width == 0) || (height == 0))          if (title[0] == 0)
280          {          {
281                  width = 800;                  strcpy(title, "rdesktop - ");
282                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
283          }          }
284    
285          strcpy(title, "rdesktop - ");          if (!ui_init())
286          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
287    
288          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
289                  return 1;                  return 1;
290    
291          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
292            memset(password, 0, sizeof(password));
293    
294          if (ui_create_window(title))          if (ui_create_window())
295          {          {
296                  rdp_main_loop();                  rdp_main_loop();
297                  ui_destroy_window();                  ui_destroy_window();
298          }          }
299    
300          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
301          rdp_disconnect();          rdp_disconnect();
302            ui_deinit();
303          return 0;          return 0;
304  }  }
305    
306    #ifdef EGD_SOCKET
307    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
308    static BOOL
309    generate_random_egd(uint8 * buf)
310    {
311            struct sockaddr_un addr;
312            BOOL ret = False;
313            int fd;
314    
315            fd = socket(AF_UNIX, SOCK_STREAM, 0);
316            if (fd == -1)
317                    return False;
318    
319            addr.sun_family = AF_UNIX;
320            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
321            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
322                    goto err;
323    
324            /* PRNGD and EGD use a simple communications protocol */
325            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
326            buf[1] = 32;            /* Number of requested random bytes */
327            if (write(fd, buf, 2) != 2)
328                    goto err;
329    
330            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
331                    goto err;
332    
333            if (read(fd, buf, 32) != 32)
334                    goto err;
335    
336            ret = True;
337    
338          err:
339            close(fd);
340            return ret;
341    }
342    #endif
343    
344  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
345  void  void
346  generate_random(uint8 * random)  generate_random(uint8 * random)
347  {  {
348          struct stat st;          struct stat st;
349          struct tms tmsbuf;          struct tms tmsbuf;
350          uint32 *r = (uint32 *) random;          MD5_CTX md5;
351          int fd;          uint32 *r;
352            int fd, n;
353    
354          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
355          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
356              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
357          {          {
358                  read(fd, random, 32);                  n = read(fd, random, 32);
359                  close(fd);                  close(fd);
360                  return;                  if (n == 32)
361                            return;
362          }          }
363    
364    #ifdef EGD_SOCKET
365            /* As a second preference use an EGD */
366            if (generate_random_egd(random))
367                    return;
368    #endif
369    
370          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
371            r = (uint32 *) random;
372          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
373          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
374          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 265  generate_random(uint8 * random) Line 377  generate_random(uint8 * random)
377          r[5] = st.st_atime;          r[5] = st.st_atime;
378          r[6] = st.st_mtime;          r[6] = st.st_mtime;
379          r[7] = st.st_ctime;          r[7] = st.st_ctime;
380    
381            /* Hash both halves with MD5 to obscure possible patterns */
382            MD5_Init(&md5);
383            MD5_Update(&md5, random, 16);
384            MD5_Final(random, &md5);
385            MD5_Update(&md5, random + 16, 16);
386            MD5_Final(random + 16, &md5);
387  }  }
388    
389  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 348  hexdump(unsigned char *p, unsigned int l Line 467  hexdump(unsigned char *p, unsigned int l
467                          printf("   ");                          printf("   ");
468    
469                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
470                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
471    
472                  printf("\n");                  printf("\n");
473                  offset += thisline;                  offset += thisline;
# Line 358  hexdump(unsigned char *p, unsigned int l Line 475  hexdump(unsigned char *p, unsigned int l
475          }          }
476  }  }
477    
478    #ifdef SAVE_LICENCE
479  int  int
480  load_licence(unsigned char **data)  load_licence(unsigned char **data)
481  {  {
# Line 411  save_licence(unsigned char *data, int le Line 529  save_licence(unsigned char *data, int le
529          write(fd, data, length);          write(fd, data, length);
530          close(fd);          close(fd);
531  }  }
532    #endif

Legend:
Removed from v.64  
changed lines
  Added in v.262

  ViewVC Help
Powered by ViewVC 1.1.26