The "rfb" library merged with VNC 4.1.1 code.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@522 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb/SConnection.cxx b/rfb/SConnection.cxx
index e969ed8..f8a3f36 100644
--- a/rfb/SConnection.cxx
+++ b/rfb/SConnection.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
- *
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ *
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -21,7 +21,6 @@
#include <rfb/secTypes.h>
#include <rfb/SMsgReaderV3.h>
#include <rfb/SMsgWriterV3.h>
-#include <rfb/SSecurity.h>
#include <rfb/SConnection.h>
#include <rfb/ServerCore.h>
@@ -41,10 +40,11 @@
const SConnection::AccessRights SConnection::AccessFull = 0xffff;
-SConnection::SConnection()
+SConnection::SConnection(SSecurityFactory* secFact, bool reverseConnection_)
: readyForSetColourMapEntries(false),
is(0), os(0), reader_(0), writer_(0),
- nSecTypes(0), security(0), state_(RFBSTATE_UNINITIALISED)
+ security(0), securityFactory(secFact), state_(RFBSTATE_UNINITIALISED),
+ reverseConnection(reverseConnection_)
{
defaultMajorVersion = 3;
defaultMinorVersion = 8;
@@ -74,15 +74,6 @@
os = os_;
}
-void SConnection::addSecType(rdr::U8 secType)
-{
- if (nSecTypes == maxSecTypes)
- throw Exception("too many security types");
- secTypes[nSecTypes++] = secType;
- vlog.debug("Offering security type %s(%d)",
- secTypeName(secType),secType);
-}
-
void SConnection::initialiseProtocol()
{
cp.writeVersion(os);
@@ -144,37 +135,40 @@
versionReceived();
+ std::list<rdr::U8> secTypes;
+ std::list<rdr::U8>::iterator i;
+ securityFactory->getSecTypes(&secTypes, reverseConnection);
+
if (cp.isVersion(3,3)) {
// cope with legacy 3.3 client only if "no authentication" or "vnc
// authentication" is supported.
-
- int i;
- for (i = 0; i < nSecTypes; i++) {
- if (secTypes[i] == secTypeNone || secTypes[i] == secTypeVncAuth) break;
+ for (i=secTypes.begin(); i!=secTypes.end(); i++) {
+ if (*i == secTypeNone || *i == secTypeVncAuth) break;
}
- if (i == nSecTypes) {
+ if (i == secTypes.end()) {
char msg[256];
sprintf(msg,"No supported security type for %d.%d client",
cp.majorVersion, cp.minorVersion);
throwConnFailedException(msg);
}
- os->writeU32(secTypes[i]);
- if (secTypes[i] == secTypeNone) os->flush();
+ os->writeU32(*i);
+ if (*i == secTypeNone) os->flush();
state_ = RFBSTATE_SECURITY;
- security = getSSecurity(secTypes[i]);
+ security = securityFactory->getSSecurity(*i, reverseConnection);
processSecurityMsg();
return;
}
// list supported security types for >=3.7 clients
- if (nSecTypes == 0)
+ if (secTypes.empty())
throwConnFailedException("No supported security types");
- os->writeU8(nSecTypes);
- os->writeBytes(secTypes, nSecTypes);
+ os->writeU8(secTypes.size());
+ for (i=secTypes.begin(); i!=secTypes.end(); i++)
+ os->writeU8(*i);
os->flush();
state_ = RFBSTATE_SECURITY_TYPE;
}
@@ -186,40 +180,33 @@
int secType = is->readU8();
vlog.info("Client requests security type %s(%d)",
secTypeName(secType),secType);
- int i;
- for (i = 0; i < nSecTypes; i++) {
- if (secType == secTypes[i]) break;
+
+ try {
+ state_ = RFBSTATE_SECURITY;
+ security = securityFactory->getSSecurity(secType, reverseConnection);
+ } catch (rdr::Exception& e) {
+ throwConnFailedException(e.str());
}
- if (i == nSecTypes) {
- char msg[256];
- sprintf(msg,"Security type %s(%d) from client not supported",
- secTypeName(secType),secType);
- throwConnFailedException(msg);
- }
- state_ = RFBSTATE_SECURITY;
- security = getSSecurity(secType);
+
processSecurityMsg();
}
void SConnection::processSecurityMsg()
{
vlog.debug("processing security message");
- bool done;
- bool ok = security->processMsg(this, &done);
- if (done) {
- state_ = RFBSTATE_QUERYING;
- if (ok) {
+ try {
+ bool done = security->processMsg(this);
+ if (done) {
+ state_ = RFBSTATE_QUERYING;
queryConnection(security->getUserName());
- } else {
- const char* failureMsg = security->failureMessage();
- if (!failureMsg) failureMsg = "Authentication failure";
- approveConnection(false, failureMsg);
}
- }
- if (!ok) {
- state_ = RFBSTATE_INVALID;
- authFailure();
- throw AuthFailureException();
+ } catch (AuthFailureException& e) {
+ vlog.error("AuthFailureException: %s", e.str());
+ os->writeU32(secResultFailed);
+ if (!cp.beforeVersion(3,8)) // 3.8 onwards have failure message
+ os->writeString(e.str());
+ os->flush();
+ throw;
}
}
@@ -264,10 +251,6 @@
{
}
-void SConnection::authFailure()
-{
-}
-
void SConnection::queryConnection(const char* userName)
{
approveConnection(true);
@@ -298,7 +281,6 @@
authSuccess();
} else {
state_ = RFBSTATE_INVALID;
- authFailure();
throw AuthFailureException(reason);
}
}