/[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 263 by astrand, Mon Nov 18 18:12:49 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;                /* If width or height are reset to zero, the geometry will
49  int height;                                     be fetched from _NET_WORKAREA */
50    int height = 600;
51  int tcp_port_rdp = TCP_PORT_RDP;  int tcp_port_rdp = TCP_PORT_RDP;
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;
59    BOOL hide_decorations = False;
60    
61  /* Display usage information */  /* Display usage information */
62  static void  static void
63  usage(char *program)  usage(char *program)
64  {  {
65          printf("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
66          printf("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
67          printf("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
68          printf("   -s: shell\n");  
69          printf("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
70          printf("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
71          printf("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
72          printf("   -k: keyboard layout\n");          fprintf(stderr, "   -s: shell\n");
73          printf("   -g: desktop geometry (WxH)\n");          fprintf(stderr, "   -c: working directory\n");
74          printf("   -f: full-screen mode\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
75          printf("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
76          printf("   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
77          printf("   -m: do not send motion events\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
78          printf("   -l: do not request licence\n");          fprintf(stderr, "   -f: full-screen mode\n");
79          printf("   -t: rdp tcp port\n\n");          fprintf(stderr, "   -b: force bitmap updates\n");
80            fprintf(stderr, "   -e: disable encryption (French TS)\n");
81            fprintf(stderr, "   -m: do not send motion events\n");
82            fprintf(stderr, "   -K: keep window manager key bindings\n");
83            fprintf(stderr, "   -T: window title\n");
84            fprintf(stderr, "   -D: hide window manager decorations\n");
85    }
86    
87    static BOOL
88    read_password(char *password, int size)
89    {
90            struct termios tios;
91            BOOL ret = False;
92            int istty = 0;
93            char *p;
94    
95            if (tcgetattr(STDIN_FILENO, &tios) == 0)
96            {
97                    fprintf(stderr, "Password: ");
98                    tios.c_lflag &= ~ECHO;
99                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
100                    istty = 1;
101            }
102    
103            if (fgets(password, size, stdin) != NULL)
104            {
105                    ret = True;
106    
107                    /* strip final newline */
108                    p = strchr(password, '\n');
109                    if (p != NULL)
110                            *p = 0;
111            }
112    
113            if (istty)
114            {
115                    tios.c_lflag |= ECHO;
116                    tcsetattr(STDIN_FILENO, TCSANOW, &tios);
117                    fprintf(stderr, "\n");
118            }
119    
120            return ret;
121  }  }
122    
123  /* Client program */  /* Client program */
124  int  int
125  main(int argc, char *argv[])  main(int argc, char *argv[])
126  {  {
127            char server[64];
128          char fullhostname[64];          char fullhostname[64];
129          char domain[16];          char domain[16];
130          char password[16];          char password[16];
131          char shell[32];          char shell[128];
132          char directory[32];          char directory[32];
133          char title[32];          BOOL prompt_password;
134          struct passwd *pw;          struct passwd *pw;
         char *server, *p;  
135          uint32 flags;          uint32 flags;
136            char *p;
137          int c;          int c;
138    
         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");  
   
139          flags = RDP_LOGON_NORMAL;          flags = RDP_LOGON_NORMAL;
140            prompt_password = False;
141          domain[0] = password[0] = shell[0] = directory[0] = 0;          domain[0] = password[0] = shell[0] = directory[0] = 0;
142          strcpy(keymapname, "us");          strcpy(keymapname, "en-us");
143    
144          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)
145          {          {
146                  switch (c)                  switch (c)
147                  {                  {
# Line 110  main(int argc, char *argv[]) Line 162  main(int argc, char *argv[])
162                                  break;                                  break;
163    
164                          case 'p':                          case 'p':
165                                    if ((optarg[0] == '-') && (optarg[1] == 0))
166                                    {
167                                            prompt_password = True;
168                                            break;
169                                    }
170    
171                                  STRNCPY(password, optarg, sizeof(password));                                  STRNCPY(password, optarg, sizeof(password));
172                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
173    
174                                    /* try to overwrite argument so it won't appear in ps */
175                                    p = optarg;
176                                    while (*p)
177                                            *(p++) = 'X';
178                                  break;                                  break;
179    
180                          case 'n':                          case 'n':
# Line 119  main(int argc, char *argv[]) Line 182  main(int argc, char *argv[])
182                                  break;                                  break;
183    
184                          case 'k':                          case 'k':
185                                  STRNCPY(keymapname, optarg,                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
                                         sizeof(keymapname));  
186                                  break;                                  break;
187    
188                          case 'g':                          case 'g':
189                                    if (!strcmp(optarg, "workarea"))
190                                    {
191                                            width = height = 0;
192                                            break;
193                                    }
194    
195                                  width = strtol(optarg, &p, 10);                                  width = strtol(optarg, &p, 10);
196                                  if (*p == 'x')                                  if (*p == 'x')
197                                          height = strtol(p + 1, NULL, 10);                                          height = strtol(p + 1, NULL, 10);
# Line 151  main(int argc, char *argv[]) Line 219  main(int argc, char *argv[])
219                                  sendmotion = False;                                  sendmotion = False;
220                                  break;                                  break;
221    
222                          case 'l':                          case 'K':
223                                  licence = False;                                  grab_keyboard = False;
224                                    break;
225    
226                            case 'T':
227                                    STRNCPY(title, optarg, sizeof(title));
228                                  break;                                  break;
229    
230                          case 't':                          case 'D':
231                                  tcp_port_rdp = strtol(optarg, NULL, 10);                                  hide_decorations = True;
232                                  break;                                  break;
233    
234                          case 'h':                          case 'h':
# Line 173  main(int argc, char *argv[]) Line 245  main(int argc, char *argv[])
245                  return 1;                  return 1;
246          }          }
247    
248          server = argv[optind];          STRNCPY(server, argv[optind], sizeof(server));
249            p = strchr(server, ':');
250            if (p != NULL)
251            {
252                    tcp_port_rdp = strtol(p + 1, NULL, 10);
253                    *p = 0;
254            }
255    
256          if (username[0] == 0)          if (username[0] == 0)
257          {          {
# Line 202  main(int argc, char *argv[]) Line 280  main(int argc, char *argv[])
280                  STRNCPY(hostname, fullhostname, sizeof(hostname));                  STRNCPY(hostname, fullhostname, sizeof(hostname));
281          }          }
282    
283          if (!strcmp(password, "-"))          if (prompt_password && read_password(password, sizeof(password)))
284          {                  flags |= RDP_LOGON_AUTO;
                 p = getpass("Password: ");  
                 if (p == NULL)  
                 {  
                         error("failed to read password\n");  
                         return 0;  
                 }  
                 STRNCPY(password, p, sizeof(password));  
         }  
285    
286          if ((width == 0) || (height == 0))          if (title[0] == 0)
287          {          {
288                  width = 800;                  strcpy(title, "rdesktop - ");
289                  height = 600;                  strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
290          }          }
291    
292          strcpy(title, "rdesktop - ");          if (!ui_init())
293          strncat(title, server, sizeof(title) - sizeof("rdesktop - "));                  return 1;
294    
295          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (!rdp_connect(server, flags, domain, password, shell, directory))
296                  return 1;                  return 1;
297    
298          printf("Connection successful.\n");          DEBUG(("Connection successful.\n"));
299            memset(password, 0, sizeof(password));
300    
301          if (ui_create_window(title))          if (ui_create_window())
302          {          {
303                  rdp_main_loop();                  rdp_main_loop();
304                  ui_destroy_window();                  ui_destroy_window();
305          }          }
306    
307          printf("Disconnecting...\n");          DEBUG(("Disconnecting...\n"));
308          rdp_disconnect();          rdp_disconnect();
309            ui_deinit();
310          return 0;          return 0;
311  }  }
312    
313    #ifdef EGD_SOCKET
314    /* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
315    static BOOL
316    generate_random_egd(uint8 * buf)
317    {
318            struct sockaddr_un addr;
319            BOOL ret = False;
320            int fd;
321    
322            fd = socket(AF_UNIX, SOCK_STREAM, 0);
323            if (fd == -1)
324                    return False;
325    
326            addr.sun_family = AF_UNIX;
327            memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
328            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
329                    goto err;
330    
331            /* PRNGD and EGD use a simple communications protocol */
332            buf[0] = 1;             /* Non-blocking (similar to /dev/urandom) */
333            buf[1] = 32;            /* Number of requested random bytes */
334            if (write(fd, buf, 2) != 2)
335                    goto err;
336    
337            if ((read(fd, buf, 1) != 1) || (buf[0] == 0))   /* Available? */
338                    goto err;
339    
340            if (read(fd, buf, 32) != 32)
341                    goto err;
342    
343            ret = True;
344    
345          err:
346            close(fd);
347            return ret;
348    }
349    #endif
350    
351  /* Generate a 32-byte random for the secure transport code. */  /* Generate a 32-byte random for the secure transport code. */
352  void  void
353  generate_random(uint8 * random)  generate_random(uint8 * random)
354  {  {
355          struct stat st;          struct stat st;
356          struct tms tmsbuf;          struct tms tmsbuf;
357          uint32 *r = (uint32 *) random;          MD5_CTX md5;
358          int fd;          uint32 *r;
359            int fd, n;
360    
361          /* If we have a kernel random device, use it. */          /* If we have a kernel random device, try that first */
362          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)          if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
363              || ((fd = open("/dev/random", O_RDONLY)) != -1))              || ((fd = open("/dev/random", O_RDONLY)) != -1))
364          {          {
365                  read(fd, random, 32);                  n = read(fd, random, 32);
366                  close(fd);                  close(fd);
367                  return;                  if (n == 32)
368                            return;
369          }          }
370    
371    #ifdef EGD_SOCKET
372            /* As a second preference use an EGD */
373            if (generate_random_egd(random))
374                    return;
375    #endif
376    
377          /* Otherwise use whatever entropy we can gather - ideas welcome. */          /* Otherwise use whatever entropy we can gather - ideas welcome. */
378            r = (uint32 *) random;
379          r[0] = (getpid()) | (getppid() << 16);          r[0] = (getpid()) | (getppid() << 16);
380          r[1] = (getuid()) | (getgid() << 16);          r[1] = (getuid()) | (getgid() << 16);
381          r[2] = times(&tmsbuf);  /* system uptime (clocks) */          r[2] = times(&tmsbuf);  /* system uptime (clocks) */
# Line 265  generate_random(uint8 * random) Line 384  generate_random(uint8 * random)
384          r[5] = st.st_atime;          r[5] = st.st_atime;
385          r[6] = st.st_mtime;          r[6] = st.st_mtime;
386          r[7] = st.st_ctime;          r[7] = st.st_ctime;
387    
388            /* Hash both halves with MD5 to obscure possible patterns */
389            MD5_Init(&md5);
390            MD5_Update(&md5, random, 16);
391            MD5_Final(random, &md5);
392            MD5_Update(&md5, random + 16, 16);
393            MD5_Final(random + 16, &md5);
394  }  }
395    
396  /* malloc; exit if out of memory */  /* malloc; exit if out of memory */
# Line 348  hexdump(unsigned char *p, unsigned int l Line 474  hexdump(unsigned char *p, unsigned int l
474                          printf("   ");                          printf("   ");
475    
476                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
477                          printf("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
478    
479                  printf("\n");                  printf("\n");
480                  offset += thisline;                  offset += thisline;
# Line 358  hexdump(unsigned char *p, unsigned int l Line 482  hexdump(unsigned char *p, unsigned int l
482          }          }
483  }  }
484    
485    #ifdef SAVE_LICENCE
486  int  int
487  load_licence(unsigned char **data)  load_licence(unsigned char **data)
488  {  {
# Line 411  save_licence(unsigned char *data, int le Line 536  save_licence(unsigned char *data, int le
536          write(fd, data, length);          write(fd, data, length);
537          close(fd);          close(fd);
538  }  }
539    #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26