summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Srb <michalsrb@gmail.com>2014-11-10 15:32:00 +0200
committerMichal Srb <michalsrb@gmail.com>2014-11-10 17:37:02 +0200
commit270a31cf172a5ea15061ae4bffdad5780e4014ad (patch)
tree0cf88039d61ace43610256b07f9d1a20d36590e1
parentdbf6355cbb69e588a4162debadb5337dd8b14ac0 (diff)
downloadtigervnc-270a31cf172a5ea15061ae4bffdad5780e4014ad.tar.gz
tigervnc-270a31cf172a5ea15061ae4bffdad5780e4014ad.zip
VncAuth: Read and use readonly password.
Try to read second password (for read only access) from rfbauth file. If client sent second password instead of first one, allow him read only access.
-rw-r--r--common/rfb/SSecurityVncAuth.cxx64
-rw-r--r--common/rfb/SSecurityVncAuth.h8
2 files changed, 47 insertions, 25 deletions
diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx
index ca81bf33..05488f67 100644
--- a/common/rfb/SSecurityVncAuth.cxx
+++ b/common/rfb/SSecurityVncAuth.cxx
@@ -49,10 +49,27 @@ VncAuthPasswdParameter SSecurityVncAuth::vncAuthPasswd
"access the server", &SSecurityVncAuth::vncAuthPasswdFile);
SSecurityVncAuth::SSecurityVncAuth(void)
- : sentChallenge(false), responsePos(0), pg(&vncAuthPasswd)
+ : sentChallenge(false), responsePos(0), pg(&vncAuthPasswd), accessRights(0)
{
}
+bool SSecurityVncAuth::verifyResponse(const PlainPasswd &password)
+{
+ rdr::U8 expectedResponse[vncAuthChallengeSize];
+
+ // Calculate the expected response
+ rdr::U8 key[8];
+ int pwdLen = strlen(password.buf);
+ for (int i=0; i<8; i++)
+ key[i] = i<pwdLen ? password.buf[i] : 0;
+ deskey(key, EN0);
+ for (int j = 0; j < vncAuthChallengeSize; j += 8)
+ des(challenge+j, expectedResponse+j);
+
+ // Check the actual response
+ return memcmp(response, expectedResponse, vncAuthChallengeSize) == 0;
+}
+
bool SSecurityVncAuth::processMsg(SConnection* sc)
{
rdr::InStream* is = sc->getInStream();
@@ -72,25 +89,23 @@ bool SSecurityVncAuth::processMsg(SConnection* sc)
if (responsePos < vncAuthChallengeSize) return false;
- PlainPasswd passwd(pg->getVncAuthPasswd());
+ PlainPasswd passwd, passwdReadOnly;
+ pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
if (!passwd.buf)
throw AuthFailureException("No password configured for VNC Auth");
- // Calculate the expected response
- rdr::U8 key[8];
- int pwdLen = strlen(passwd.buf);
- for (int i=0; i<8; i++)
- key[i] = i<pwdLen ? passwd.buf[i] : 0;
- deskey(key, EN0);
- for (int j = 0; j < vncAuthChallengeSize; j += 8)
- des(challenge+j, challenge+j);
+ if (verifyResponse(passwd)) {
+ accessRights = SConnection::AccessDefault;
+ return true;
+ }
- // Check the actual response
- if (memcmp(challenge, response, vncAuthChallengeSize) != 0)
- throw AuthFailureException();
+ if (passwdReadOnly.buf && verifyResponse(passwdReadOnly)) {
+ accessRights = SConnection::AccessView;
+ return true;
+ }
- return true;
+ throw AuthFailureException();
}
VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name,
@@ -99,8 +114,8 @@ VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name,
: BinaryParameter(name, desc, 0, 0, ConfServer), passwdFile(passwdFile_) {
}
-char* VncAuthPasswdParameter::getVncAuthPasswd() {
- ObfuscatedPasswd obfuscated;
+void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword) {
+ ObfuscatedPasswd obfuscated, obfuscatedReadOnly;
getData((void**)&obfuscated.buf, &obfuscated.length);
if (obfuscated.length == 0) {
@@ -108,18 +123,20 @@ char* VncAuthPasswdParameter::getVncAuthPasswd() {
CharArray fname(passwdFile->getData());
if (!fname.buf[0]) {
vlog.info("neither %s nor %s params set", getName(), passwdFile->getName());
- return 0;
+ return;
}
FILE* fp = fopen(fname.buf, "r");
if (!fp) {
vlog.error("opening password file '%s' failed",fname.buf);
- return 0;
+ return;
}
vlog.debug("reading password file");
- obfuscated.buf = new char[128];
- obfuscated.length = fread(obfuscated.buf, 1, 128, fp);
+ obfuscated.buf = new char[8];
+ obfuscated.length = fread(obfuscated.buf, 1, 8, fp);
+ obfuscatedReadOnly.buf = new char[8];
+ obfuscatedReadOnly.length = fread(obfuscatedReadOnly.buf, 1, 8, fp);
fclose(fp);
} else {
vlog.info("%s parameter not set", getName());
@@ -127,10 +144,11 @@ char* VncAuthPasswdParameter::getVncAuthPasswd() {
}
try {
- PlainPasswd password(obfuscated);
- return password.takeBuf();
+ PlainPasswd plainPassword(obfuscated);
+ password->replaceBuf(plainPassword.takeBuf());
+ PlainPasswd plainPasswordReadOnly(obfuscatedReadOnly);
+ readOnlyPassword->replaceBuf(plainPasswordReadOnly.takeBuf());
} catch (...) {
- return 0;
}
}
diff --git a/common/rfb/SSecurityVncAuth.h b/common/rfb/SSecurityVncAuth.h
index 8a2d0f62..1aa3a274 100644
--- a/common/rfb/SSecurityVncAuth.h
+++ b/common/rfb/SSecurityVncAuth.h
@@ -25,6 +25,7 @@
#define __RFB_SSECURITYVNCAUTH_H__
#include <rfb/Configuration.h>
+#include <rfb/Password.h>
#include <rfb/SSecurity.h>
#include <rfb/Security.h>
#include <rdr/types.h>
@@ -35,13 +36,13 @@ namespace rfb {
public:
// getPasswd() returns a string or null if unsuccessful. The
// SSecurityVncAuth object delete[]s the string when done.
- virtual char* getVncAuthPasswd()=0;
+ virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword)=0;
};
class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter {
public:
VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_);
- virtual char* getVncAuthPasswd();
+ virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword);
protected:
StringParameter* passwdFile;
};
@@ -52,15 +53,18 @@ namespace rfb {
virtual bool processMsg(SConnection* sc);
virtual int getType() const {return secTypeVncAuth;}
virtual const char* getUserName() const {return 0;}
+ virtual SConnection::AccessRights getAccessRights() const { return accessRights; }
static StringParameter vncAuthPasswdFile;
static VncAuthPasswdParameter vncAuthPasswd;
private:
+ bool verifyResponse(const PlainPasswd &password);
enum {vncAuthChallengeSize = 16};
rdr::U8 challenge[vncAuthChallengeSize];
rdr::U8 response[vncAuthChallengeSize];
bool sentChallenge;
int responsePos;
VncAuthPasswdGetter* pg;
+ SConnection::AccessRights accessRights;
};
}
#endif