Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

rdesktop.cpp

Go to the documentation of this file.
00001 /*
00002    rdesktop: A Remote Desktop Protocol client.
00003    Entrypoint and utility functions
00004    Copyright (C) Matthew Chapman 1999-2003
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 //#include <stdarg.h>           /* va_list va_start va_end */
00022 #include <unistd.h>             /* read close getuid getgid getpid getppid gethostname */
00023 #include <fcntl.h>              /* open */
00024 #include <pwd.h>                /* getpwuid */
00025 //#include <termios.h>          /* tcgetattr tcsetattr */
00026 #include <sys/stat.h>           /* stat */
00027 #include <sys/time.h>           /* gettimeofday */
00028 #include <sys/times.h>          /* times */
00029 #include <errno.h>
00030 #include "rdesktop.h"
00031 
00032 #ifdef EGD_SOCKET
00033 #include <sys/socket.h>         /* socket connect */
00034 #include <sys/un.h>             /* sockaddr_un */
00035 #endif
00036 
00037 //#ifdef WITH_OPENSSL
00038 #include <openssl/md5.h>
00039 //#else
00040 //#include "crypto/md5.h"
00041 //#endif
00042 
00043 /*extern "C" */void ui_main_loop(void);
00044 
00045 int g_argc;
00046 char ** g_argv;
00047 
00048 char title[32] = "";
00049 char username[16] = "j";
00050 char hostname[16] = "sharp";
00051 char keymapname[16];
00052 int keylayout = 0x409;          /* Defaults to US keyboard layout */
00053 int g_width = 800;              /* If width or height are reset to zero, the geometry will
00054                                    be fetched from _NET_WORKAREA */
00055 int g_height = 600;
00056 int tcp_port_rdp = TCP_PORT_RDP;
00057 int server_bpp = 8;
00058 int win_button_size = 0;        /* If zero, disable single app mode */
00059 BOOL bitmap_compression = True;
00060 BOOL sendmotion = True;
00061 BOOL orders = True;
00062 BOOL encryption = True;
00063 BOOL desktop_save = True;
00064 BOOL fullscreen = False;
00065 BOOL grab_keyboard = True;
00066 BOOL hide_decorations = False;
00067 extern BOOL owncolmap;
00068 
00069 /* report an unimplemented protocol feature */
00070 void
00071 unimpl(char *format, ...)
00072 {
00073 }
00074 
00075 /* malloc; exit if out of memory */
00076 void *
00077 xmalloc(int size)
00078 {
00079    void *mem = malloc(size);
00080         if (mem == NULL)
00081         {
00082                 error("xmalloc %d\n", size);
00083                 exit(1);
00084         }
00085         return mem;
00086 }
00087 
00088 /* realloc; exit if out of memory */
00089 void *
00090 xrealloc(void *oldmem, int size)
00091 {
00092         void *mem = realloc(oldmem, size);
00093         if (mem == NULL)
00094         {
00095                 error("xrealloc %d\n", size);
00096                 exit(1);
00097         }
00098         return mem;
00099 }
00100 
00101 /* free */
00102 void
00103 xfree(void *mem)
00104 {
00105         free(mem);
00106 }
00107 
00108 /* report an error */
00109 void
00110 error(char *format, ...)
00111 {
00112 }
00113 
00114 /* report a warning */
00115 void
00116 warning(char *format, ...)
00117 {
00118 }
00119 
00120 /* Generate a 32-byte random for the secure transport code. */
00121 void
00122 generate_random(uint8 * random)
00123 {
00124         struct stat st;
00125         struct tms tmsbuf;
00126         MD5_CTX md5;
00127         uint32 *r;
00128         int fd, n;
00129 
00130         /* If we have a kernel random device, try that first */
00131         if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
00132             || ((fd = open("/dev/random", O_RDONLY)) != -1))
00133         {
00134                 n = read(fd, random, 32);
00135                 close(fd);
00136                 if (n == 32)
00137                         return;
00138         }
00139         /* Otherwise use whatever entropy we can gather - ideas welcome. */
00140         r = (uint32 *) random;
00141         r[0] = (getpid()) | (getppid() << 16);
00142         r[1] = (getuid()) | (getgid() << 16);
00143         r[2] = times(&tmsbuf);  /* system uptime (clocks) */
00144         gettimeofday((struct timeval *) &r[3], NULL);   /* sec and usec */
00145         stat("/tmp", &st);
00146         r[5] = st.st_atime;
00147         r[6] = st.st_mtime;
00148         r[7] = st.st_ctime;
00149 
00150         /* Hash both halves with MD5 to obscure possible patterns */
00151         MD5_Init(&md5);
00152         MD5_Update(&md5, random, 16);
00153         MD5_Final(random, &md5);
00154         MD5_Update(&md5, random + 16, 16);
00155         MD5_Final(random + 16, &md5);
00156 }
00157 
00158 int
00159 load_licence(unsigned char **data)
00160 {
00161         char *path;
00162         char *home;
00163         struct stat st;
00164         int fd;
00165 
00166         home = getenv("HOME");
00167         if (home == NULL)
00168                 return -1;
00169 
00170         path = (char*)xmalloc(strlen(home) + strlen(hostname) + 20);
00171         sprintf(path, "%s/.rdesktop/licence.%s", home, hostname);
00172 
00173         fd = open(path, O_RDONLY);
00174         if (fd == -1)
00175                 return -1;
00176 
00177         if (fstat(fd, &st))
00178                 return -1;
00179 
00180         *data = (unsigned char*)xmalloc(st.st_size);
00181         return read(fd, *data, st.st_size);
00182 }
00183 
00184 void
00185 save_licence(unsigned char *data, int length)
00186 {
00187         char *fpath;            /* file path for licence */
00188         char *fname, *fnamewrk; /* file name for licence .inkl path. */
00189         char *home;
00190         uint32 y;
00191         struct flock fnfl;
00192         int fnfd, fnwrkfd, i, wlen;
00193         struct stream s, *s_ptr;
00194         uint32 len;
00195 
00196         /* Construct a stream, so that we can use macros to extract the
00197          * licence.
00198          */
00199         s_ptr = &s;
00200         s_ptr->p = data;
00201         /* Skip first two bytes */
00202         in_uint16(s_ptr, len);
00203 
00204         /* Skip three strings */
00205         for (i = 0; i < 3; i++)
00206         {
00207                 in_uint32(s_ptr, len);
00208                 s_ptr->p += len;
00209                 /* Make sure that we won't be past the end of data after
00210                  * reading the next length value
00211                  */
00212                 if ((s_ptr->p) + 4 > data + length)
00213                 {
00214                         printf("Error in parsing licence key.\n");
00215                         printf("Strings %d end value %x > supplied length (%x)\n", i,
00216                                (unsigned int) s_ptr->p, (unsigned int) data + length);
00217                         return;
00218                 }
00219         }
00220         in_uint32(s_ptr, len);
00221         if (s_ptr->p + len > data + length)
00222         {
00223                 printf("Error in parsing licence key.\n");
00224                 printf("End of licence %x > supplied length (%x)\n",
00225                        (unsigned int) s_ptr->p + len, (unsigned int) data + length);
00226                 return;
00227         }
00228 
00229         home = getenv("HOME");
00230         if (home == NULL)
00231                 return;
00232 
00233         /* set and create the directory -- if it doesn't exist. */
00234         fpath = (char*)xmalloc(strlen(home) + 11);
00235         STRNCPY(fpath, home, strlen(home) + 1);
00236 
00237         sprintf(fpath, "%s/.rdesktop", fpath);
00238         if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
00239         {
00240                 perror("mkdir");
00241                 exit(1);
00242         }
00243 
00244         /* set the real licence filename, and put a write lock on it. */
00245         fname = (char*)xmalloc(strlen(fpath) + strlen(hostname) + 10);
00246         sprintf(fname, "%s/licence.%s", fpath, hostname);
00247         fnfd = open(fname, O_RDONLY);
00248         if (fnfd != -1)
00249         {
00250                 fnfl.l_type = F_WRLCK;
00251                 fnfl.l_whence = SEEK_SET;
00252                 fnfl.l_start = 0;
00253                 fnfl.l_len = 1;
00254                 fcntl(fnfd, F_SETLK, &fnfl);
00255         }
00256 
00257         /* create a temporary licence file */
00258         fnamewrk = (char*)xmalloc(strlen(fname) + 12);
00259         for (y = 0;; y++)
00260         {
00261                 sprintf(fnamewrk, "%s.%lu", fname, (long unsigned int) y);
00262                 fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
00263                 if (fnwrkfd == -1)
00264                 {
00265                         if (errno == EINTR || errno == EEXIST)
00266                                 continue;
00267                         perror("create");
00268                         exit(1);
00269                 }
00270                 break;
00271         }
00272         /* write to the licence file */
00273         for (y = 0; y < len;)
00274         {
00275                 do
00276                 {
00277                         wlen = write(fnwrkfd, s_ptr->p + y, len - y);
00278                 }
00279                 while (wlen == -1 && errno == EINTR);
00280                 if (wlen < 1)
00281                 {
00282                         perror("write");
00283                         unlink(fnamewrk);
00284                         exit(1);
00285                 }
00286                 y += wlen;
00287         }
00288 
00289         /* close the file and rename it to fname */
00290         if (close(fnwrkfd) == -1)
00291         {
00292                 perror("close");
00293                 unlink(fnamewrk);
00294                 exit(1);
00295         }
00296         if (rename(fnamewrk, fname) == -1)
00297         {
00298                 perror("rename");
00299                 unlink(fnamewrk);
00300                 exit(1);
00301         }
00302         /* close the file lock on fname */
00303         if (fnfd != -1)
00304         {
00305                 fnfl.l_type = F_UNLCK;
00306                 fnfl.l_whence = SEEK_SET;
00307                 fnfl.l_start = 0;
00308                 fnfl.l_len = 1;
00309                 fcntl(fnfd, F_SETLK, &fnfl);
00310                 close(fnfd);
00311         }
00312 
00313 }

Generated on Sat Nov 5 16:17:42 2005 for OPIE by  doxygen 1.4.2