diff -urN vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/vncviewer/argsresources.c --- vnc_unixsrc.orig/vncviewer/argsresources.c 2003-03-04 11:18:23.000000000 -0800 +++ vnc_unixsrc/vncviewer/argsresources.c 2003-04-18 11:53:03.000000000 -0700 @@ -1,4 +1,5 @@ /* + * Copyright (C) 2003 Workspot, Inc. All Rights Reserved. * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This is free software; you can redistribute it and/or modify @@ -141,6 +142,12 @@ {"passwordFile", "PasswordFile", XtRString, sizeof(String), XtOffsetOf(AppData, passwordFile), XtRImmediate, (XtPointer) 0}, + {"configFile", "ConfigFile", XtRString, sizeof(String), + XtOffsetOf(AppData, configFile), XtRImmediate, (XtPointer) 0}, + + {"quiet", "Quiet", XtRBool, sizeof(Bool), + XtOffsetOf(AppData, quiet), XtRImmediate, (XtPointer) False}, + {"passwordDialog", "PasswordDialog", XtRBool, sizeof(Bool), XtOffsetOf(AppData, passwordDialog), XtRImmediate, (XtPointer) False}, @@ -215,6 +222,8 @@ {"-fullscreen", "*fullScreen", XrmoptionNoArg, "True"}, {"-noraiseonbeep", "*raiseOnBeep", XrmoptionNoArg, "False"}, {"-passwd", "*passwordFile", XrmoptionSepArg, 0}, + {"-config", "*configFile", XrmoptionSepArg, 0}, + {"-quiet", "*quiet", XrmoptionNoArg, "True"}, {"-encodings", "*encodings", XrmoptionSepArg, 0}, {"-bgr233", "*useBGR233", XrmoptionNoArg, "True"}, {"-owncmap", "*forceOwnCmap", XrmoptionNoArg, "True"}, @@ -249,6 +258,14 @@ /* + * We use a fixed key to store passwords, since we assume that our local + * file system is secure but nonetheless don't want to store passwords + * as plaintext. + */ + +extern char fixedkey[]; + +/* * removeArgs() is used to remove some of command line arguments. */ @@ -284,6 +301,8 @@ " -fullscreen\n" " -noraiseonbeep\n" " -passwd \n" + " -config \n" + " -quiet\n" " -encodings (e.g. \"tight copyrect\")\n" " -bgr233\n" " -owncmap\n" @@ -317,6 +336,11 @@ XtGetApplicationResources(toplevel, &appData, appDataResourceList, XtNumber(appDataResourceList), 0, 0); + /* close stderr if quiet */ + if (appData.quiet) { + fclose(stderr); + } + /* Add our actions to the actions table so they can be used in widget resource specs */ @@ -336,33 +360,242 @@ return; } - if (argc == 1) { - vncServerName = DoServerDialog(); - appData.passwordDialog = True; - } else if (argc != 2) { - usage(); - } else { - vncServerName = argv[1]; - - if (vncServerName[0] == '-') - usage(); + if (appData.configFile) { + loadConfigFile(); } + else { + if (argc == 1) { + vncServerName = DoServerDialog(); + appData.passwordDialog = True; + } else if (argc != 2) { + usage(); + } else { + vncServerName = argv[1]; + + if (vncServerName[0] == '-') + usage(); + } + + if (strlen(vncServerName) > 255) { + fprintf(stderr,"VNC server name too long\n"); + exit(1); + } + + for (i = 0; vncServerName[i] != ':' && vncServerName[i] != 0; i++); - if (strlen(vncServerName) > 255) { - fprintf(stderr,"VNC server name too long\n"); - exit(1); + strncpy(vncServerHost, vncServerName, i); + + if (vncServerName[i] == ':') { + vncServerPort = atoi(&vncServerName[i+1]); + } else { + vncServerPort = 0; + } } - for (i = 0; vncServerName[i] != ':' && vncServerName[i] != 0; i++); + if (vncServerPort < 100) + vncServerPort += SERVER_PORT_OFFSET; +} + +/* + * loadConfigFile reads a config file and set the corresponding + * application data structure + * + * Format of config file: + * + * [connection] + * host= # vncServerHost + * port= # vncServerPort + * password= # appData.password + * + * [options] + * use_encoding_0=1 # raw + * use_encoding_1=1 # copyrect + * use_encoding_2=1 # rre + * use_encoding_3=1 + * use_encoding_4=1 # corre + * use_encoding_5=1 # hextile + * use_encoding_6=1 # zlib + * use_encoding_7=1 # tight + * use_encoding_8=1 # not implemented in vnc_unixsrc/vncviewer + * preferred_encoding=7 # appData.encodingsString + * restricted=0 # not applicable in vnc_unixsrc/vncviewer + * viewonly=0 # appData.viewOnly + * fullscreen=0 # appData.fullScreen + * 8bit=0 # appData.useBGR233 + * shared=1 # appData.shareDesktop + * swapmouse=0 # not implemented in vnc_unixsrc/vncviewer + * belldeiconify=0 # appData.raiseOnBeep + * emulate3=1 # not implemented in vnc_unixsrc/vncviewer + * emulate3timeout=100 # not implemented in vnc_unixsrc/vncviewer + * emulate3fuzz=4 # not implemented in vnc_unixsrc/vncviewer + * disableclipboard=0 # not configurable in vnc_unixsrc/vncviewer + * localcursor=1 # not configurable in vnc_unixsrc/vncviewer + * scale_den=1 # not applicable in vnc_unixsrc/vncviewer + * scale_num=1 # not applicable in vnc_unixsrc/vncviewer + * cursorshape=1 # appData.useRemoteCursor + * noremotecursor=0 # not configurable in vnc_unixsrc/vncviewer + * compresslevel=-1 # appData.compressLevel + * quality=-1 # appData.qualityLevel + */ + +#define LASTENCODING rfbEncodingZlibHex + +void loadConfigFile() { + int nSection; + int nEncoding; + int i; + regex_t regexSection; + regex_t regexKeyVal; + regmatch_t matchLine[3]; + FILE* pFile; + char* pszKey; + char* pszVal; + char szLine[80]; + char szEncoding[] = "use_encoding_"; + char* aszEncodings[] = { "raw", + "copyrect", + "rre", + "", + "corre", + "hextile", + "zlib", + "tight", + "" }; + + + if (appData.configFile && (pFile = fopen(appData.configFile, "r"))) { + regcomp(®exSection, "\\[(.+?)\\]", REG_EXTENDED | REG_NEWLINE); + regcomp(®exKeyVal, "(.+?)=(.*)", REG_EXTENDED | REG_NEWLINE); + + nSection = 0; + while (fgets(szLine, 80, pFile)) { + if (regexec(®exSection, szLine, 3, matchLine, 0) == 0) { + if ((matchLine[1].rm_so >= 0) && + (matchLine[1].rm_eo > matchLine[1].rm_so)) { + /* section */ + szLine[matchLine[1].rm_eo] = '\0'; + pszKey = (char*) szLine+matchLine[1].rm_so; + if (strcmp(pszKey, "connection") == 0) { + nSection = 1; + } + else if (strcmp(pszKey, "options") == 0) { + nSection = 2; + } + } + } + else if (regexec(®exKeyVal, szLine, 3, matchLine, 0) == 0) { + if ((matchLine[1].rm_so >= 0) && + (matchLine[1].rm_eo > matchLine[1].rm_so) && + (matchLine[2].rm_so >= 0) && + (matchLine[2].rm_eo > matchLine[2].rm_so)) { + /* key */ + szLine[matchLine[1].rm_eo] = '\0'; + pszKey = (char*) szLine+matchLine[1].rm_so; + + /* val */ + szLine[matchLine[2].rm_eo] = '\0'; + pszVal = (char*) szLine+matchLine[2].rm_so; + + if (nSection == 1) { + /* [connection] */ + if (strcmp(pszKey, "host") == 0) { + strncpy(vncServerHost, pszVal, 255); + } + else if (strcmp(pszKey, "port") == 0) { + vncServerPort = atoi(pszVal); + } + else if (strcmp(pszKey, "password") == 0) { + for (i = 0; i < MAXPWLEN; i++) { + sscanf(pszVal+i*2, "%2x", &nEncoding); + appData.password[i] = (unsigned char) nEncoding; + } + } + } + else if (nSection == 2) { + /* [options] */ + if (strncmp(pszKey, szEncoding, strlen(szEncoding)) == 0) { + + /* position pszKey at the encoding index */ + pszKey += strlen(szEncoding); + nEncoding = atoi(pszKey); + + if ((rfbEncodingRaw <= nEncoding) && + (nEncoding <= LASTENCODING)) { + if (atoi(pszVal) == 0) { + *(aszEncodings[nEncoding]) = '\0'; + } + } + } + else if (strcmp(pszKey, "preferred_encoding") == 0) { + nEncoding = atoi(pszVal); + if ((rfbEncodingRaw <= nEncoding) && + (nEncoding <= LASTENCODING)) { + strcpy(appData.szEncodings, aszEncodings[nEncoding]); + } + + for (i = LASTENCODING; i >= rfbEncodingRaw; i--) { + if ((i != nEncoding) && + *(aszEncodings[i]) && + ((strlen(appData.szEncodings) + + strlen(aszEncodings[i]) + + 1) < 255)) { + strcat(appData.szEncodings, " "); + strcat(appData.szEncodings, aszEncodings[i]); + } + } + } + else if (strcmp(pszKey, "viewonly") == 0) { + appData.viewOnly = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "fullscreen") == 0) { + appData.fullScreen = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "8bit") == 0) { + appData.useBGR233 = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "shared") == 0) { + appData.shareDesktop = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "belldeiconify") == 0) { + appData.raiseOnBeep = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "cursorshape") == 0) { + appData.useRemoteCursor = atoi(pszVal) == 1 ? True : False; + } + else if (strcmp(pszKey, "compresslevel") == 0) { + appData.compressLevel = atoi(pszVal); + } + else if (strcmp(pszKey, "quality") == 0) { + appData.qualityLevel = atoi(pszVal); + } + } + } + } + } + + fclose(pFile); - strncpy(vncServerHost, vncServerName, i); + regfree(®exSection); + regfree(®exKeyVal); - if (vncServerName[i] == ':') { - vncServerPort = atoi(&vncServerName[i+1]); - } else { - vncServerPort = 0; + appData.encodingsString = appData.szEncodings; } +} - if (vncServerPort < 100) - vncServerPort += SERVER_PORT_OFFSET; + +/* + * vncDecryptPasswd decrypts password set from config file + */ + +char* vncDecryptPasswd() { + unsigned int i; + + + deskey(fixedkey, DE1); + des(appData.password, appData.password); + + appData.password[MAXPWLEN] = 0; + + return appData.password; } + diff -urN vnc_unixsrc.orig/vncviewer/Imakefile vnc_unixsrc/vncviewer/Imakefile --- vnc_unixsrc.orig/vncviewer/Imakefile 2003-03-04 11:18:23.000000000 -0800 +++ vnc_unixsrc/vncviewer/Imakefile 2003-04-18 11:52:11.000000000 -0700 @@ -13,7 +13,8 @@ DEFINES = -DMITSHM #endif -INCLUDES = -I../include -I. -I/usr/include +VNCAUTH_INC = -I../libvncauth +INCLUDES = -I../include $(VNCAUTH_INC) -I. -I/usr/include VNCAUTH_LIB = ../libvncauth/libvncauth.a ZLIB_LIB = -lz JPEG_LIB = -ljpeg diff -urN vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c --- vnc_unixsrc.orig/vncviewer/rfbproto.c 2003-03-04 11:18:23.000000000 -0800 +++ vnc_unixsrc/vncviewer/rfbproto.c 2003-04-18 11:54:53.000000000 -0700 @@ -1,4 +1,5 @@ /* + * Copyright (C) 2003 Workspot, Inc. All Rights Reserved. * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. @@ -205,7 +206,10 @@ case rfbVncAuth: if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return False; - if (appData.passwordFile) { + if (appData.password[0]) { + passwd = vncDecryptPasswd(); + } + else if (appData.passwordFile) { passwd = vncDecryptPasswdFromFile(appData.passwordFile); if (!passwd) { fprintf(stderr,"Cannot read valid password from file \"%s\"\n", diff -urN vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncviewer/vncviewer.h --- vnc_unixsrc.orig/vncviewer/vncviewer.h 2003-03-04 11:18:23.000000000 -0800 +++ vnc_unixsrc/vncviewer/vncviewer.h 2003-04-18 11:55:26.000000000 -0700 @@ -1,4 +1,5 @@ /* + * Copyright (C) 2003 Workspot, Inc. All Rights Reserved. * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +38,8 @@ #include #include #include "rfbproto.h" +#include "vncauth.h" +#include "d3des.h" extern int endianTest; @@ -71,6 +75,7 @@ Bool raiseOnBeep; String encodingsString; + char szEncodings[256]; Bool useBGR233; int nColours; @@ -85,6 +90,9 @@ int wmDecorationHeight; char *passwordFile; + char *configFile; + char password[MAXPWLEN+1]; + Bool quiet; Bool passwordDialog; int rawDelay; @@ -117,6 +125,8 @@ extern void removeArgs(int *argc, char** argv, int idx, int nargs); extern void usage(void); extern void GetArgsAndResources(int argc, char **argv); +extern void loadConfigFile(); +extern char* vncDecryptPasswd(); /* colour.c */