/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/rdesktop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 25 by matty, Sat Jan 6 03:47:04 2001 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-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 motion = True;  BOOL bitmap_compression = True;
52    BOOL sendmotion = True;
53  BOOL orders = True;  BOOL orders = True;
54  BOOL licence = True;  BOOL encryption = True;
55    BOOL desktop_save = True;
56    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          STATUS("Usage: %s [options] server\n", program);          fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
65          STATUS("   -u: user name\n");          fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2002 Matt Chapman.\n");
66          STATUS("   -d: domain\n");          fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
67          STATUS("   -s: shell\n");  
68          STATUS("   -c: working directory\n");          fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
69          STATUS("   -p: password (autologon)\n");          fprintf(stderr, "   -u: user name\n");
70          STATUS("   -n: client hostname\n");          fprintf(stderr, "   -d: domain\n");
71          STATUS("   -w: desktop width\n");          fprintf(stderr, "   -s: shell\n");
72          STATUS("   -h: desktop height\n");          fprintf(stderr, "   -c: working directory\n");
73          STATUS("   -k: keyboard layout (hex)\n");          fprintf(stderr, "   -p: password (- to prompt)\n");
74          STATUS("   -b: force bitmap updates\n");          fprintf(stderr, "   -n: client hostname\n");
75          STATUS("   -m: do not send motion events\n");          fprintf(stderr, "   -k: keyboard layout on terminal server (us,sv,gr,etc.)\n");
76          STATUS("   -l: do not request licence\n\n");          fprintf(stderr, "   -g: desktop geometry (WxH)\n");
77            fprintf(stderr, "   -f: full-screen mode\n");
78            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          struct passwd *pw;          char server[64];
127          char *server;          char fullhostname[64];
         uint32 flags;  
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;
134            uint32 flags;
135            char *p;
136          int c;          int c;
137    
         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");  
   
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, "en-us");
142    
143          while ((c = getopt(argc, argv, "u:d:s:c:p:n:w:h:k:bml?")) != -1)          while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemKT:Dh?")) != -1)
144          {          {
145                  switch (c)                  switch (c)
146                  {                  {
147                          case 'u':                          case 'u':
148                                  strncpy(username, optarg, sizeof(username));                                  STRNCPY(username, optarg, sizeof(username));
149                                  break;                                  break;
150    
151                          case 'd':                          case 'd':
152                                  strncpy(domain, optarg, sizeof(domain));                                  STRNCPY(domain, optarg, sizeof(domain));
153                                    break;
154    
155                            case 's':
156                                    STRNCPY(shell, optarg, sizeof(shell));
157                                    break;
158    
159                            case 'c':
160                                    STRNCPY(directory, optarg, sizeof(directory));
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));
171                                  flags |= RDP_LOGON_AUTO;                                  flags |= RDP_LOGON_AUTO;
172                                  strncpy(password, optarg, sizeof(password));  
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 's':                          case 'n':
180                                  strncpy(shell, optarg, sizeof(shell));                                  STRNCPY(hostname, optarg, sizeof(hostname));
181                                  break;                                  break;
182    
183                          case 'c':                          case 'k':
184                                  strncpy(directory, optarg, sizeof(directory));                                  STRNCPY(keymapname, optarg, sizeof(keymapname));
185                                  break;                                  break;
186    
187                          case 'n':                          case 'g':
188                                  strncpy(hostname, optarg, sizeof(hostname));                                  width = strtol(optarg, &p, 10);
189                                    if (*p == 'x')
190                                            height = strtol(p + 1, NULL, 10);
191    
192                                    if ((width == 0) || (height == 0))
193                                    {
194                                            error("invalid geometry\n");
195                                            return 1;
196                                    }
197                                  break;                                  break;
198    
199                          case 'w':                          case 'f':
200                                  width = strtol(optarg, NULL, 10);                                  fullscreen = True;
201                                  break;                                  break;
202    
203                          case 'h':                          case 'b':
204                                  height = strtol(optarg, NULL, 10);                                  orders = False;
205                                  break;                                  break;
206    
207                          case 'k':                          case 'e':
208                                  keylayout = strtol(optarg, NULL, 16);                                  encryption = False;
209                                  break;                                  break;
210    
211                          case 'm':                          case 'm':
212                                  motion = False;                                  sendmotion = False;
213                                  break;                                  break;
214    
215                          case 'b':                          case 'K':
216                                  orders = False;                                  grab_keyboard = False;
217                                  break;                                  break;
218    
219                          case 'l':                          case 'T':
220                                  licence = False;                                  STRNCPY(title, optarg, sizeof(title));
221                                  break;                                  break;
222    
223                            case 'D':
224                                    hide_decorations = True;
225                                    break;
226    
227                            case 'h':
228                          case '?':                          case '?':
229                          default:                          default:
230                                  usage(argv[0]);                                  usage(argv[0]);
# Line 143  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          {          {
251                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
252                  if ((pw == NULL) || (pw->pw_name == NULL))                  if ((pw == NULL) || (pw->pw_name == NULL))
253                  {                  {
254                          STATUS("Could not determine user name.\n");                          error("could not determine username, use -u\n");
255                          return 1;                          return 1;
256                  }                  }
257    
258                  strncpy(username, pw->pw_name, sizeof(username));                  STRNCPY(username, pw->pw_name, sizeof(username));
259          }          }
260    
261          if (hostname[0] == 0)          if (hostname[0] == 0)
262          {          {
263                  if (gethostname(hostname, sizeof(hostname)) == -1)                  if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
264                  {                  {
265                          STATUS("Could not determine host name.\n");                          error("could not determine local hostname, use -n\n");
266                          return 1;                          return 1;
267                  }                  }
268    
269                    p = strchr(fullhostname, '.');
270                    if (p != NULL)
271                            *p = 0;
272    
273                    STRNCPY(hostname, fullhostname, sizeof(hostname));
274          }          }
275    
276          if (!rdp_connect(server, flags, domain, password, shell, directory))          if (prompt_password && read_password(password, sizeof(password)))
277                    flags |= RDP_LOGON_AUTO;
278    
279            if (title[0] == 0)
280            {
281                    strcpy(title, "rdesktop - ");
282                    strncat(title, server, sizeof(title) - sizeof("rdesktop - "));
283            }
284    
285            if (!ui_init())
286                  return 1;                  return 1;
287    
288          STATUS("Connection successful.\n");          if (!rdp_connect(server, flags, domain, password, shell, directory))
289                    return 1;
290    
291          strcpy(title, "rdesktop - ");          DEBUG(("Connection successful.\n"));
292          strncat(title, server, sizeof(title));          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            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          /* If we have a kernel random device, use it. */  
354          if ((fd = open("/dev/urandom", O_RDONLY)) != -1)          /* If we have a kernel random device, try that first */
355            if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
356                || ((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 210  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 219  xmalloc(int size) Line 393  xmalloc(int size)
393          void *mem = malloc(size);          void *mem = malloc(size);
394          if (mem == NULL)          if (mem == NULL)
395          {          {
396                  ERROR("xmalloc %d\n", size);                  error("xmalloc %d\n", size);
397                  exit(1);                  exit(1);
398          }          }
399          return mem;          return mem;
# Line 232  xrealloc(void *oldmem, int size) Line 406  xrealloc(void *oldmem, int size)
406          void *mem = realloc(oldmem, size);          void *mem = realloc(oldmem, size);
407          if (mem == NULL)          if (mem == NULL)
408          {          {
409                  ERROR("xrealloc %d\n", size);                  error("xrealloc %d\n", size);
410                  exit(1);                  exit(1);
411          }          }
412          return mem;          return mem;
# Line 245  xfree(void *mem) Line 419  xfree(void *mem)
419          free(mem);          free(mem);
420  }  }
421    
422  /* Produce a hex dump */  /* report an error */
423    void
424    error(char *format, ...)
425    {
426            va_list ap;
427    
428            fprintf(stderr, "ERROR: ");
429    
430            va_start(ap, format);
431            vfprintf(stderr, format, ap);
432            va_end(ap);
433    }
434    
435    /* report an unimplemented protocol feature */
436    void
437    unimpl(char *format, ...)
438    {
439            va_list ap;
440    
441            fprintf(stderr, "NOT IMPLEMENTED: ");
442    
443            va_start(ap, format);
444            vfprintf(stderr, format, ap);
445            va_end(ap);
446    }
447    
448    /* produce a hex dump */
449  void  void
450  hexdump(unsigned char *p, unsigned int len)  hexdump(unsigned char *p, unsigned int len)
451  {  {
# Line 255  hexdump(unsigned char *p, unsigned int l Line 455  hexdump(unsigned char *p, unsigned int l
455    
456          while (offset < len)          while (offset < len)
457          {          {
458                  STATUS("%04x ", offset);                  printf("%04x ", offset);
459                  thisline = len - offset;                  thisline = len - offset;
460                  if (thisline > 16)                  if (thisline > 16)
461                          thisline = 16;                          thisline = 16;
462    
463                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
464                          STATUS("%02x ", line[i]) for (; i < 16; i++)                          printf("%02x ", line[i]);
465                                  STATUS("   ");  
466                    for (; i < 16; i++)
467                            printf("   ");
468    
469                  for (i = 0; i < thisline; i++)                  for (i = 0; i < thisline; i++)
470                          STATUS("%c",                          printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
                                (line[i] >= 0x20  
                                 && line[i] < 0x7f) ? line[i] : '.');  
471    
472                  STATUS("\n");                  printf("\n");
473                  offset += thisline;                  offset += thisline;
474                  line += thisline;                  line += thisline;
475          }          }
476  }  }
477    
478    #ifdef SAVE_LICENCE
479    int
480    load_licence(unsigned char **data)
481    {
482            char path[PATH_MAX];
483            char *home;
484            struct stat st;
485            int fd;
486    
487            home = getenv("HOME");
488            if (home == NULL)
489                    return -1;
490    
491            STRNCPY(path, home, sizeof(path));
492            strncat(path, "/.rdesktop/licence", sizeof(path) - strlen(path) - 1);
493    
494            fd = open(path, O_RDONLY);
495            if (fd == -1)
496                    return -1;
497    
498            if (fstat(fd, &st))
499                    return -1;
500    
501            *data = xmalloc(st.st_size);
502            return read(fd, *data, st.st_size);
503    }
504    
505    void
506    save_licence(unsigned char *data, int length)
507    {
508            char path[PATH_MAX];
509            char *home;
510            int fd;
511    
512            home = getenv("HOME");
513            if (home == NULL)
514                    return;
515    
516            STRNCPY(path, home, sizeof(path));
517            strncat(path, "/.rdesktop", sizeof(path) - strlen(path) - 1);
518            mkdir(path, 0700);
519    
520            strncat(path, "/licence", sizeof(path) - strlen(path) - 1);
521    
522            fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
523            if (fd == -1)
524            {
525                    perror("open");
526                    return;
527            }
528    
529            write(fd, data, length);
530            close(fd);
531    }
532    #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26