git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@522 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -44,10 +44,6 @@ CConnection::~CConnection() | |||
deleteReaderAndWriter(); | |||
} | |||
void CConnection::setServerName(const char* serverName_) { | |||
serverName.buf = strDup(serverName_); | |||
} | |||
void CConnection::deleteReaderAndWriter() | |||
{ | |||
delete reader_; | |||
@@ -207,10 +203,7 @@ void CConnection::processSecurityTypesMsg() | |||
void CConnection::processSecurityMsg() | |||
{ | |||
vlog.debug("processing security message"); | |||
bool done; | |||
if (!security->processMsg(this, &done)) | |||
throwAuthFailureException(); | |||
if (done) { | |||
if (security->processMsg(this)) { | |||
state_ = RFBSTATE_SECURITY_RESULT; | |||
processSecurityResultMsg(); | |||
} | |||
@@ -229,17 +222,23 @@ void CConnection::processSecurityResultMsg() | |||
switch (result) { | |||
case secResultOK: | |||
securityCompleted(); | |||
break; | |||
return; | |||
case secResultFailed: | |||
vlog.debug("auth failed"); | |||
throwAuthFailureException(); | |||
break; | |||
case secResultTooMany: | |||
vlog.debug("auth failed - too many tries"); | |||
throwAuthFailureException(); | |||
break; | |||
default: | |||
vlog.error("unknown security result"); | |||
throwAuthFailureException(); | |||
}; | |||
throw Exception("Unknown security result from server"); | |||
} | |||
CharArray reason; | |||
if (cp.beforeVersion(3,8)) | |||
reason.buf = strDup("Authentication failure"); | |||
else | |||
reason.buf = is->readString(); | |||
state_ = RFBSTATE_INVALID; | |||
throw AuthFailureException(reason.buf); | |||
} | |||
void CConnection::processInitMsg() | |||
@@ -248,20 +247,6 @@ void CConnection::processInitMsg() | |||
reader_->readServerInit(); | |||
} | |||
void CConnection::throwAuthFailureException() | |||
{ | |||
CharArray reason; | |||
vlog.debug("state=%d, ver=%d.%d", state(), cp.majorVersion, cp.minorVersion); | |||
if (state()==RFBSTATE_SECURITY_RESULT && !cp.beforeVersion(3,8)) { | |||
reason.buf = is->readString(); | |||
} else { | |||
reason.buf = strDup("Authentication failure"); | |||
} | |||
state_ = RFBSTATE_INVALID; | |||
vlog.error(reason.buf); | |||
throw AuthFailureException(reason.buf); | |||
} | |||
void CConnection::throwConnFailedException() | |||
{ | |||
state_ = RFBSTATE_INVALID; |
@@ -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 | |||
@@ -41,11 +41,14 @@ namespace rfb { | |||
CConnection(); | |||
virtual ~CConnection(); | |||
// *** | |||
void setServerName(const char* serverName_); | |||
// Methods to initialise the connection | |||
// setServerName() is used to provide a unique(ish) name for the server to | |||
// which we are connected. This might be the result of getPeerEndpoint on | |||
// a TcpSocket, for example, or a host specified by DNS name & port. | |||
// The serverName is used when verifying the Identity of a host (see RA2). | |||
void setServerName(const char* name_) { serverName.replaceBuf(strDup(name_)); } | |||
// setStreams() sets the streams to be used for the connection. These must | |||
// be set before initialiseProtocol() and processMsg() are called. The | |||
// CSecurity object may call setStreams() again to provide alternative | |||
@@ -129,7 +132,9 @@ namespace rfb { | |||
rdr::InStream* getInStream() { return is; } | |||
rdr::OutStream* getOutStream() { return os; } | |||
char* getServerName() {return strDup(serverName.buf);} | |||
// Access method used by SSecurity implementations that can verify servers' | |||
// Identities, to determine the unique(ish) name of the server. | |||
const char* getServerName() const { return serverName.buf; } | |||
enum stateEnum { | |||
RFBSTATE_UNINITIALISED, |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -34,7 +34,7 @@ void CMsgHandler::setDesktopSize(int width, int height) | |||
cp.height = height; | |||
} | |||
void CMsgHandler::setCursor(const Point& hotspot, const Point& size, void* data, void* mask) | |||
void CMsgHandler::setCursor(int w, int h, const Point& hotspot, void* data, void* mask) | |||
{ | |||
} | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -36,8 +36,15 @@ namespace rfb { | |||
CMsgHandler(); | |||
virtual ~CMsgHandler(); | |||
// The following methods are called as corresponding messages are read. A | |||
// derived class should override these methods as desired. Note that for | |||
// the setDesktopSize(), setPixelFormat() and setName() methods, a derived | |||
// class should call on to CMsgHandler's methods to set the members of cp | |||
// appropriately. | |||
virtual void setDesktopSize(int w, int h); | |||
virtual void setCursor(const Point& hotspot, const Point& size, void* data, void* mask); | |||
virtual void setCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask); | |||
virtual void setPixelFormat(const PixelFormat& pf); | |||
virtual void setName(const char* name); | |||
virtual void serverInit(); |
@@ -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 | |||
@@ -41,10 +41,6 @@ CMsgReader::~CMsgReader() | |||
delete [] imageBuf; | |||
} | |||
void CMsgReader::endMsg() | |||
{ | |||
} | |||
void CMsgReader::readSetColourMapEntries() | |||
{ | |||
is->skip(1); | |||
@@ -53,13 +49,11 @@ void CMsgReader::readSetColourMapEntries() | |||
rdr::U16Array rgbs(nColours * 3); | |||
for (int i = 0; i < nColours * 3; i++) | |||
rgbs.buf[i] = is->readU16(); | |||
endMsg(); | |||
handler->setColourMapEntries(firstColour, nColours, rgbs.buf); | |||
} | |||
void CMsgReader::readBell() | |||
{ | |||
endMsg(); | |||
handler->bell(); | |||
} | |||
@@ -75,19 +69,16 @@ void CMsgReader::readServerCutText() | |||
CharArray ca(len+1); | |||
ca.buf[len] = 0; | |||
is->readBytes(ca.buf, len); | |||
endMsg(); | |||
handler->serverCutText(ca.buf, len); | |||
} | |||
void CMsgReader::readFramebufferUpdateStart() | |||
{ | |||
endMsg(); | |||
handler->framebufferUpdateStart(); | |||
} | |||
void CMsgReader::readFramebufferUpdateEnd() | |||
{ | |||
endMsg(); | |||
handler->framebufferUpdateEnd(); | |||
} | |||
@@ -128,17 +119,17 @@ void CMsgReader::readCopyRect(const Rect& r) | |||
handler->copyRect(r, srcX, srcY); | |||
} | |||
void CMsgReader::readSetCursor(const Point& hotspot, const Point& size) | |||
void CMsgReader::readSetCursor(int width, int height, const Point& hotspot) | |||
{ | |||
int data_len = size.x * size.y * (handler->cp.pf().bpp/8); | |||
int mask_len = ((size.x+7)/8) * size.y; | |||
int data_len = width * height * (handler->cp.pf().bpp/8); | |||
int mask_len = ((width+7)/8) * height; | |||
rdr::U8Array data(data_len); | |||
rdr::U8Array mask(mask_len); | |||
is->readBytes(data.buf, data_len); | |||
is->readBytes(mask.buf, mask_len); | |||
handler->setCursor(hotspot, size, data.buf, mask.buf); | |||
handler->setCursor(width, height, hotspot, data.buf, mask.buf); | |||
} | |||
rdr::U8* CMsgReader::getImageBuf(int required, int requested, int* nPixels) |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -53,15 +53,13 @@ namespace rfb { | |||
virtual void readBell(); | |||
virtual void readServerCutText(); | |||
virtual void endMsg(); | |||
virtual void readFramebufferUpdateStart(); | |||
virtual void readFramebufferUpdateEnd(); | |||
virtual void readRect(const Rect& r, unsigned int encoding); | |||
virtual void readCopyRect(const Rect& r); | |||
virtual void readSetCursor(const Point& hotspot, const Point& size); | |||
virtual void readSetCursor(int width, int height, const Point& hotspot); | |||
CMsgReader(CMsgHandler* handler, rdr::InStream* is); | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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,6 +21,7 @@ | |||
#include <rdr/InStream.h> | |||
#include <rfb/CMsgReaderV3.h> | |||
#include <rfb/CMsgHandler.h> | |||
#include <rfb/util.h> | |||
using namespace rfb; | |||
@@ -41,10 +42,8 @@ void CMsgReaderV3::readServerInit() | |||
PixelFormat pf; | |||
pf.read(is); | |||
handler->setPixelFormat(pf); | |||
char* name = is->readString(); | |||
handler->setName(name); | |||
delete [] name; | |||
endMsg(); | |||
CharArray name(is->readString()); | |||
handler->setName(name.buf); | |||
handler->serverInit(); | |||
} | |||
@@ -85,7 +84,7 @@ void CMsgReaderV3::readMsg() | |||
handler->setDesktopSize(w, h); | |||
break; | |||
case pseudoEncodingCursor: | |||
readSetCursor(Point(x, y), Point(w, h)); | |||
readSetCursor(w, h, Point(x,y)); | |||
break; | |||
case pseudoEncodingLastRect: | |||
nUpdateRectsLeft = 1; // this rectangle is the last one | |||
@@ -104,6 +103,5 @@ void CMsgReaderV3::readFramebufferUpdate() | |||
{ | |||
is->skip(1); | |||
nUpdateRectsLeft = is->readU16(); | |||
endMsg(); | |||
handler->framebufferUpdateStart(); | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -96,7 +96,7 @@ void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental) | |||
} | |||
void CMsgWriter::writeKeyEvent(rdr::U32 key, bool down) | |||
void CMsgWriter::keyEvent(rdr::U32 key, bool down) | |||
{ | |||
startMsg(msgTypeKeyEvent); | |||
os->writeU8(down); | |||
@@ -106,22 +106,23 @@ void CMsgWriter::writeKeyEvent(rdr::U32 key, bool down) | |||
} | |||
void CMsgWriter::writePointerEvent(int x, int y, int buttonMask) | |||
void CMsgWriter::pointerEvent(const Point& pos, int buttonMask) | |||
{ | |||
if (x < 0) x = 0; | |||
if (y < 0) y = 0; | |||
if (x >= cp->width) x = cp->width - 1; | |||
if (y >= cp->height) y = cp->height - 1; | |||
Point p(pos); | |||
if (p.x < 0) p.x = 0; | |||
if (p.y < 0) p.y = 0; | |||
if (p.x >= cp->width) p.x = cp->width - 1; | |||
if (p.y >= cp->height) p.y = cp->height - 1; | |||
startMsg(msgTypePointerEvent); | |||
os->writeU8(buttonMask); | |||
os->writeU16(x); | |||
os->writeU16(y); | |||
os->writeU16(p.x); | |||
os->writeU16(p.y); | |||
endMsg(); | |||
} | |||
void CMsgWriter::writeClientCutText(const char* str, int len) | |||
void CMsgWriter::clientCutText(const char* str, int len) | |||
{ | |||
startMsg(msgTypeClientCutText); | |||
os->pad(3); | |||
@@ -129,8 +130,3 @@ void CMsgWriter::writeClientCutText(const char* str, int len) | |||
os->writeBytes(str, len); | |||
endMsg(); | |||
} | |||
void CMsgWriter::setOutStream(rdr::OutStream* os_) | |||
{ | |||
os = os_; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -22,7 +22,7 @@ | |||
#ifndef __RFB_CMSGWRITER_H__ | |||
#define __RFB_CMSGWRITER_H__ | |||
#include <rdr/types.h> | |||
#include <rfb/InputHandler.h> | |||
namespace rdr { class OutStream; } | |||
@@ -32,24 +32,25 @@ namespace rfb { | |||
class ConnParams; | |||
struct Rect; | |||
class CMsgWriter { | |||
class CMsgWriter : public InputHandler { | |||
public: | |||
virtual ~CMsgWriter(); | |||
// CMsgWriter abstract interface methods | |||
virtual void writeClientInit(bool shared)=0; | |||
virtual void startMsg(int type)=0; | |||
virtual void endMsg()=0; | |||
// CMsgWriter implemented methods | |||
virtual void writeSetPixelFormat(const PixelFormat& pf); | |||
virtual void writeSetEncodings(int nEncodings, rdr::U32* encodings); | |||
virtual void writeSetEncodings(int preferredEncoding, bool useCopyRect); | |||
virtual void writeFramebufferUpdateRequest(const Rect& r,bool incremental); | |||
virtual void writeKeyEvent(rdr::U32 key, bool down); | |||
virtual void writePointerEvent(int x, int y, int buttonMask); | |||
virtual void writeClientCutText(const char* str, int len); | |||
virtual void startMsg(int type)=0; | |||
virtual void endMsg()=0; | |||
virtual void setOutStream(rdr::OutStream* os); | |||
// InputHandler implementation | |||
virtual void keyEvent(rdr::U32 key, bool down); | |||
virtual void pointerEvent(const Point& pos, int buttonMask); | |||
virtual void clientCutText(const char* str, int len); | |||
ConnParams* getConnParams() { return cp; } | |||
rdr::OutStream* getOutStream() { return os; } |
@@ -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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -18,10 +18,14 @@ | |||
// | |||
// CSecurity - class on the client side for handling security handshaking. A | |||
// derived class for a particular security type overrides the processMsg() | |||
// method. processMsg() is called first when the security type has been | |||
// decided on, and will keep being called whenever there is data to read from | |||
// the server until either it returns false, indicating authentication/security | |||
// failure, or it returns with done set to true, to indicate success. | |||
// method. | |||
// processMsg() is called first when the security type has been decided on, and | |||
// will keep being called whenever there is data to read from the server. It | |||
// should return false when it needs more data, or true when the security | |||
// handshaking is over and we are now waiting for the SecurityResult message | |||
// from the server. In the event of failure a suitable exception should be | |||
// thrown. | |||
// | |||
// Note that the first time processMsg() is called, there is no guarantee that | |||
// there is any data to read from the CConnection's InStream, but subsequent | |||
@@ -39,7 +43,7 @@ namespace rfb { | |||
class CSecurity { | |||
public: | |||
virtual ~CSecurity() {} | |||
virtual bool processMsg(CConnection* cc, bool* done)=0; | |||
virtual bool processMsg(CConnection* cc)=0; | |||
virtual void destroy() { delete this; } | |||
virtual int getType() const = 0; | |||
virtual const char* description() const = 0; |
@@ -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 | |||
@@ -28,9 +28,7 @@ namespace rfb { | |||
class CSecurityNone : public CSecurity { | |||
public: | |||
virtual bool processMsg(CConnection* cc, bool* done) { | |||
*done = true; return true; | |||
} | |||
virtual bool processMsg(CConnection* cc) { return true; } | |||
virtual int getType() const {return secTypeNone;} | |||
virtual const char* description() const {return "No Encryption";} | |||
}; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -18,19 +18,25 @@ | |||
// | |||
// CSecurityVncAuth | |||
// | |||
// XXX not thread-safe, because d3des isn't - do we need to worry about this? | |||
// | |||
#include <string.h> | |||
#include <stdio.h> | |||
#include <rfb/CConnection.h> | |||
#include <rfb/UserPasswdGetter.h> | |||
#include <rfb/vncAuth.h> | |||
#include <rfb/Password.h> | |||
#include <rfb/CSecurityVncAuth.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/util.h> | |||
extern "C" { | |||
#include <rfb/d3des.h> | |||
} | |||
using namespace rfb; | |||
static LogWriter vlog("VncAuth"); | |||
static const int vncAuthChallengeSize = 16; | |||
CSecurityVncAuth::CSecurityVncAuth(UserPasswdGetter* upg_) | |||
: upg(upg_) | |||
@@ -41,23 +47,28 @@ CSecurityVncAuth::~CSecurityVncAuth() | |||
{ | |||
} | |||
bool CSecurityVncAuth::processMsg(CConnection* cc, bool* done) | |||
bool CSecurityVncAuth::processMsg(CConnection* cc) | |||
{ | |||
*done = false; | |||
rdr::InStream* is = cc->getInStream(); | |||
rdr::OutStream* os = cc->getOutStream(); | |||
// Read the challenge & obtain the user's password | |||
rdr::U8 challenge[vncAuthChallengeSize]; | |||
is->readBytes(challenge, vncAuthChallengeSize); | |||
CharArray passwd; | |||
if (!upg->getUserPasswd(0, &passwd.buf)) { | |||
vlog.error("Getting password failed"); | |||
return false; | |||
} | |||
vncAuthEncryptChallenge(challenge, passwd.buf); | |||
memset(passwd.buf, 0, strlen(passwd.buf)); | |||
PlainPasswd passwd; | |||
upg->getUserPasswd(0, &passwd.buf); | |||
// Calculate the correct 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); | |||
// Return the response to the server | |||
os->writeBytes(challenge, vncAuthChallengeSize); | |||
os->flush(); | |||
*done = true; | |||
return true; | |||
} |
@@ -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 | |||
@@ -20,7 +20,6 @@ | |||
#include <rfb/CSecurity.h> | |||
#include <rfb/secTypes.h> | |||
#include <rfb/vncAuth.h> | |||
namespace rfb { | |||
@@ -30,7 +29,7 @@ namespace rfb { | |||
public: | |||
CSecurityVncAuth(UserPasswdGetter* pg); | |||
virtual ~CSecurityVncAuth(); | |||
virtual bool processMsg(CConnection* cc, bool* done); | |||
virtual bool processMsg(CConnection* cc); | |||
virtual int getType() const {return secTypeVncAuth;}; | |||
virtual const char* description() const {return "No Encryption";} | |||
private: |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 |
@@ -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 | |||
@@ -24,8 +24,7 @@ | |||
using namespace rfb; | |||
ComparingUpdateTracker::ComparingUpdateTracker(PixelBuffer* buffer) | |||
: SimpleUpdateTracker(true), fb(buffer), | |||
oldFb(fb->getPF(), 0, 0), firstCompare(true) | |||
: fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true) | |||
{ | |||
changed.assign_union(fb->getRect()); | |||
} | |||
@@ -35,19 +34,6 @@ ComparingUpdateTracker::~ComparingUpdateTracker() | |||
} | |||
void ComparingUpdateTracker::flush_update(UpdateInfo* info, | |||
const Region& cliprgn, int maxArea) | |||
{ | |||
throw rfb::Exception("flush_update(UpdateInfo*) not implemented"); | |||
} | |||
void ComparingUpdateTracker::flush_update(UpdateTracker &ut, | |||
const Region &cliprgn) | |||
{ | |||
throw rfb::Exception("flush_update(UpdateTracker&) not implemented"); | |||
} | |||
#define BLOCK_SIZE 16 | |||
void ComparingUpdateTracker::compare() | |||
@@ -60,7 +46,7 @@ void ComparingUpdateTracker::compare() | |||
// since in effect the entire framebuffer has changed. | |||
oldFb.setSize(fb->width(), fb->height()); | |||
for (int y=0; y<fb->height(); y+=BLOCK_SIZE) { | |||
Rect pos(0, y, fb->width(), vncmin(fb->height(), y+BLOCK_SIZE)); | |||
Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE)); | |||
int srcStride; | |||
const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride); | |||
oldFb.imageRect(pos, srcData, srcStride); | |||
@@ -100,20 +86,20 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged) | |||
for (int blockTop = r.tl.y; blockTop < r.br.y; blockTop += BLOCK_SIZE) | |||
{ | |||
// Get a strip of the source buffer | |||
Rect pos(r.tl.x, blockTop, r.br.x, vncmin(r.br.y, blockTop+BLOCK_SIZE)); | |||
Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE)); | |||
int fbStride; | |||
const rdr::U8* newBlockPtr = fb->getPixelsR(pos, &fbStride); | |||
int newStrideBytes = fbStride * bytesPerPixel; | |||
rdr::U8* oldBlockPtr = oldData; | |||
int blockBottom = vncmin(blockTop+BLOCK_SIZE, r.br.y); | |||
int blockBottom = __rfbmin(blockTop+BLOCK_SIZE, r.br.y); | |||
for (int blockLeft = r.tl.x; blockLeft < r.br.x; blockLeft += BLOCK_SIZE) | |||
{ | |||
const rdr::U8* newPtr = newBlockPtr; | |||
rdr::U8* oldPtr = oldBlockPtr; | |||
int blockRight = vncmin(blockLeft+BLOCK_SIZE, r.br.x); | |||
int blockRight = __rfbmin(blockLeft+BLOCK_SIZE, r.br.x); | |||
int blockWidthInBytes = (blockRight-blockLeft) * bytesPerPixel; | |||
for (int y = blockTop; y < blockBottom; y++) |
@@ -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 | |||
@@ -32,10 +32,6 @@ namespace rfb { | |||
// as appropriate. | |||
virtual void compare(); | |||
virtual void flush_update(UpdateInfo* info, const Region& cliprgn, | |||
int maxArea); | |||
virtual void flush_update(UpdateTracker &info, const Region &cliprgn); | |||
private: | |||
void compareRect(const Rect& r, Region* newchanged); | |||
PixelBuffer* fb; |
@@ -1,6 +1,6 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. | |||
* Copyright (C) 2004-2005 Cendio AB. 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 | |||
@@ -32,15 +32,19 @@ | |||
#include <rfb/Configuration.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/Exception.h> | |||
#ifdef WIN32 | |||
// Under Win32, we use these routines from several threads, | |||
// so we must provide suitable locking. | |||
#include <rfb/Threading.h> | |||
static rfb::Mutex configLock; | |||
#ifdef __RFB_THREADING_IMPL | |||
// On platforms that support Threading, we use Locks to make getData safe | |||
#define LOCK_CONFIG Lock l(*configLock()) | |||
rfb::Mutex* configLock_ = 0; | |||
static rfb::Mutex* configLock() { | |||
if (!configLock_) | |||
configLock_ = new rfb::Mutex; | |||
return configLock_; | |||
} | |||
#else | |||
#define LOCK_CONFIG | |||
#endif | |||
#include <rdr/HexOutStream.h> | |||
@@ -51,15 +55,47 @@ using namespace rfb; | |||
static LogWriter vlog("Config"); | |||
// -=- Configuration | |||
// -=- The Global Configuration object | |||
Configuration* Configuration::global_ = 0; | |||
Configuration* Configuration::global() { | |||
if (!global_) | |||
global_ = new Configuration("Global"); | |||
return global_; | |||
} | |||
VoidParameter* Configuration::head = 0; | |||
bool Configuration::setParam(const char* n, const char* v, bool immutable) { | |||
return setParam(n, strlen(n), v, immutable); | |||
// -=- Configuration implementation | |||
Configuration::Configuration(const char* name_, Configuration* attachToGroup) | |||
: name(strDup(name_)), head(0), _next(0) { | |||
if (attachToGroup) { | |||
_next = attachToGroup->_next; | |||
attachToGroup->_next = this; | |||
} | |||
} | |||
bool Configuration::setParam(const char* name, int len, | |||
Configuration& Configuration::operator=(const Configuration& src) { | |||
VoidParameter* current = head; | |||
while (current) { | |||
VoidParameter* srcParam = ((Configuration&)src).get(current->getName()); | |||
if (srcParam) { | |||
current->immutable = false; | |||
CharArray value(srcParam->getValueStr()); | |||
vlog.debug("operator=(%s, %s)", current->getName(), value.buf); | |||
current->setParam(value.buf); | |||
} | |||
current = current->_next; | |||
} | |||
if (_next) | |||
*_next=src; | |||
return *this; | |||
} | |||
bool Configuration::set(const char* n, const char* v, bool immutable) { | |||
return set(n, strlen(n), v, immutable); | |||
} | |||
bool Configuration::set(const char* name, int len, | |||
const char* val, bool immutable) | |||
{ | |||
VoidParameter* current = head; | |||
@@ -75,10 +111,10 @@ bool Configuration::setParam(const char* name, int len, | |||
} | |||
current = current->_next; | |||
} | |||
return false; | |||
return _next ? _next->set(name, len, val, immutable) : false; | |||
} | |||
bool Configuration::setParam(const char* config, bool immutable) { | |||
bool Configuration::set(const char* config, bool immutable) { | |||
bool hyphen = false; | |||
if (config[0] == '-') { | |||
hyphen = true; | |||
@@ -87,7 +123,7 @@ bool Configuration::setParam(const char* config, bool immutable) { | |||
} | |||
const char* equal = strchr(config, '='); | |||
if (equal) { | |||
return setParam(config, equal-config, equal+1, immutable); | |||
return set(config, equal-config, equal+1, immutable); | |||
} else if (hyphen) { | |||
VoidParameter* current = head; | |||
while (current) { | |||
@@ -101,10 +137,10 @@ bool Configuration::setParam(const char* config, bool immutable) { | |||
current = current->_next; | |||
} | |||
} | |||
return false; | |||
return _next ? _next->set(config, immutable) : false; | |||
} | |||
VoidParameter* Configuration::getParam(const char* param) | |||
VoidParameter* Configuration::get(const char* param) | |||
{ | |||
VoidParameter* current = head; | |||
while (current) { | |||
@@ -112,11 +148,13 @@ VoidParameter* Configuration::getParam(const char* param) | |||
return current; | |||
current = current->_next; | |||
} | |||
return 0; | |||
return _next ? _next->get(param) : 0; | |||
} | |||
void Configuration::listParams(int width, int nameWidth) { | |||
void Configuration::list(int width, int nameWidth) { | |||
VoidParameter* current = head; | |||
fprintf(stderr, "%s Parameters:\n", name.buf); | |||
while (current) { | |||
char* def_str = current->getDefaultStr(); | |||
const char* desc = current->getDescription(); | |||
@@ -150,14 +188,20 @@ void Configuration::listParams(int width, int nameWidth) { | |||
} | |||
current = current->_next; | |||
} | |||
if (_next) | |||
_next->list(width, nameWidth); | |||
} | |||
// -=- VoidParameter | |||
VoidParameter::VoidParameter(const char* name_, const char* desc_) | |||
VoidParameter::VoidParameter(const char* name_, const char* desc_, Configuration* conf) | |||
: immutable(false), _hasBeenSet(false), name(name_), description(desc_) { | |||
_next = Configuration::head; | |||
Configuration::head = this; | |||
if (!conf) | |||
conf = Configuration::global(); | |||
_next = conf->head; | |||
conf->head = this; | |||
} | |||
VoidParameter::~VoidParameter() { | |||
@@ -200,8 +244,8 @@ VoidParameter::hasBeenSet() { | |||
// -=- AliasParameter | |||
AliasParameter::AliasParameter(const char* name_, const char* desc_, | |||
VoidParameter* param_) | |||
: VoidParameter(name_, desc_), param(param_) { | |||
VoidParameter* param_, Configuration* conf) | |||
: VoidParameter(name_, desc_, conf), param(param_) { | |||
} | |||
bool | |||
@@ -235,8 +279,8 @@ AliasParameter::setImmutable() { | |||
// -=- BoolParameter | |||
BoolParameter::BoolParameter(const char* name_, const char* desc_, bool v) | |||
: VoidParameter(name_, desc_), value(v), def_value(v) { | |||
BoolParameter::BoolParameter(const char* name_, const char* desc_, bool v, Configuration* conf) | |||
: VoidParameter(name_, desc_, conf), value(v), def_value(v) { | |||
} | |||
bool | |||
@@ -271,15 +315,11 @@ void BoolParameter::setParam(bool b) { | |||
char* | |||
BoolParameter::getDefaultStr() const { | |||
char* result = new char[8]; | |||
sprintf(result, "%d", (int)def_value); | |||
return result; | |||
return strDup(def_value ? "1" : "0"); | |||
} | |||
char* BoolParameter::getValueStr() const { | |||
char* result = new char[8]; | |||
sprintf(result, "%d", (int)value); | |||
return result; | |||
return strDup(value ? "1" : "0"); | |||
} | |||
bool BoolParameter::isBool() const { | |||
@@ -292,15 +332,21 @@ BoolParameter::operator bool() const { | |||
// -=- IntParameter | |||
IntParameter::IntParameter(const char* name_, const char* desc_, int v) | |||
: VoidParameter(name_, desc_), value(v), def_value(v) { | |||
IntParameter::IntParameter(const char* name_, const char* desc_, int v, | |||
int minValue_, int maxValue_, Configuration* conf) | |||
: VoidParameter(name_, desc_, conf), value(v), def_value(v), | |||
minValue(minValue_), maxValue(maxValue_) | |||
{ | |||
} | |||
bool | |||
IntParameter::setParam(const char* v) { | |||
if (immutable) return true; | |||
vlog.debug("set %s(Int) to %s", getName(), v); | |||
value = atoi(v); | |||
int i = atoi(v); | |||
if (i < minValue || i > maxValue) | |||
return false; | |||
value = i; | |||
return true; | |||
} | |||
@@ -308,6 +354,8 @@ bool | |||
IntParameter::setParam(int v) { | |||
if (immutable) return true; | |||
vlog.debug("set %s(Int) to %d", getName(), v); | |||
if (v < minValue || v > maxValue) | |||
return false; | |||
value = v; | |||
return true; | |||
} | |||
@@ -332,8 +380,8 @@ IntParameter::operator int() const { | |||
// -=- StringParameter | |||
StringParameter::StringParameter(const char* name_, const char* desc_, | |||
const char* v) | |||
: VoidParameter(name_, desc_), value(strDup(v)), def_value(v) | |||
const char* v, Configuration* conf) | |||
: VoidParameter(name_, desc_, conf), value(strDup(v)), def_value(v) | |||
{ | |||
if (!v) { | |||
fprintf(stderr,"Default value <null> for %s not allowed\n",name_); | |||
@@ -346,14 +394,12 @@ StringParameter::~StringParameter() { | |||
} | |||
bool StringParameter::setParam(const char* v) { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
if (immutable) return true; | |||
if (!v) | |||
throw rfb::Exception("setParam(<null>) not allowed"); | |||
vlog.debug("set %s(String) to %s", getName(), v); | |||
strFree(value); | |||
CharArray oldValue(value); | |||
value = strDup(v); | |||
return value != 0; | |||
} | |||
@@ -363,16 +409,14 @@ char* StringParameter::getDefaultStr() const { | |||
} | |||
char* StringParameter::getValueStr() const { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
return strDup(value); | |||
} | |||
// -=- BinaryParameter | |||
BinaryParameter::BinaryParameter(const char* name_, const char* desc_, const void* v, int l) | |||
: VoidParameter(name_, desc_), value(0), length(0), def_value((char*)v), def_length(l) { | |||
BinaryParameter::BinaryParameter(const char* name_, const char* desc_, const void* v, int l, Configuration* conf) | |||
: VoidParameter(name_, desc_, conf), value(0), length(0), def_value((char*)v), def_length(l) { | |||
if (l) { | |||
value = new char[l]; | |||
length = l; | |||
@@ -385,18 +429,14 @@ BinaryParameter::~BinaryParameter() { | |||
} | |||
bool BinaryParameter::setParam(const char* v) { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
if (immutable) return true; | |||
vlog.debug("set %s(Binary) to %s", getName(), v); | |||
return rdr::HexInStream::hexStrToBin(v, &value, &length); | |||
} | |||
void BinaryParameter::setParam(const void* v, int len) { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
if (immutable) return; | |||
vlog.debug("set %s(Binary)", getName()); | |||
delete [] value; value = 0; | |||
@@ -412,16 +452,12 @@ char* BinaryParameter::getDefaultStr() const { | |||
} | |||
char* BinaryParameter::getValueStr() const { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
return rdr::HexOutStream::binToHexStr(value, length); | |||
} | |||
void BinaryParameter::getData(void** data_, int* length_) const { | |||
#ifdef WIN32 | |||
Lock l(configLock); | |||
#endif | |||
LOCK_CONFIG; | |||
if (length_) *length_ = length; | |||
if (data_) { | |||
*data_ = new char[length]; |
@@ -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 | |||
@@ -27,38 +27,106 @@ | |||
// Simply defining a new parameter and associating it with a Configuration | |||
// will allow it to be configured by the user. | |||
// | |||
// The Configuration class is used to allow multiple distinct configurations | |||
// to co-exist at the same time. A process serving several desktops, for | |||
// instance, can create a Configuration instance for each, to allow them | |||
// to be configured independently, from the command-line, registry, etc. | |||
// If no Configuration is specified when creating a Parameter, then the | |||
// global Configuration will be assumed. | |||
// | |||
// Configurations can be "chained" into groups. Each group has a root | |||
// Configuration, a pointer to which should be passed to the constructors | |||
// of the other group members. set() and get() operations called on the | |||
// root will iterate through all of the group's members. | |||
// | |||
// NB: On platforms that support Threading, locking is performed to protect | |||
// complex parameter types from concurrent access (e.g. strings). | |||
// NB: NO LOCKING is performed when linking Configurations to groups | |||
// or when adding Parameters to Configurations. | |||
#ifndef __RFB_CONFIGURATION_H__ | |||
#define __RFB_CONFIGURATION_H__ | |||
#include <rfb/util.h> | |||
namespace rfb { | |||
class VoidParameter; | |||
struct ParameterIterator; | |||
// -=- Configuration | |||
// Class used to access parameters. | |||
class Configuration { | |||
public: | |||
// - Create a new Configuration object | |||
Configuration(const char* name, Configuration* attachToGroup=0); | |||
// - Return the buffer containing the Configuration's name | |||
const char* getName() const { return name.buf; } | |||
// - Assignment operator. For every Parameter in this Configuration's | |||
// group, get()s the corresponding source parameter and copies its | |||
// content. | |||
Configuration& operator=(const Configuration& src); | |||
// - Set named parameter to value | |||
static bool setParam(const char* param, const char* value, bool immutable=false); | |||
bool set(const char* param, const char* value, bool immutable=false); | |||
// - Set parameter to value (separated by "=") | |||
static bool setParam(const char* config, bool immutable=false); | |||
bool set(const char* config, bool immutable=false); | |||
// - Set named parameter to value, with name truncated at len | |||
static bool setParam(const char* name, int len, | |||
const char* val, bool immutable); | |||
bool set(const char* name, int len, | |||
const char* val, bool immutable); | |||
// - Get named parameter | |||
static VoidParameter* getParam(const char* param); | |||
VoidParameter* get(const char* param); | |||
// - List the parameters of this Configuration group | |||
void list(int width=79, int nameWidth=10); | |||
// - readFromFile | |||
// Read configuration parameters from the specified file. | |||
void readFromFile(const char* filename); | |||
// - writeConfigToFile | |||
// Write a new configuration parameters file, then mv it | |||
// over the old file. | |||
void writeToFile(const char* filename); | |||
// - Get the Global Configuration object | |||
// NB: This call does NOT lock the Configuration system. | |||
// ALWAYS ensure that if you have ANY global Parameters, | |||
// then they are defined as global objects, to ensure that | |||
// global() is called when only the main thread is running. | |||
static Configuration* global(); | |||
static void listParams(int width=79, int nameWidth=10); | |||
// - Container for process-wide Global parameters | |||
static bool setParam(const char* param, const char* value, bool immutable=false) { | |||
return global()->set(param, value, immutable); | |||
} | |||
static bool setParam(const char* config, bool immutable=false) { | |||
return global()->set(config, immutable); | |||
} | |||
static bool setParam(const char* name, int len, | |||
const char* val, bool immutable) { | |||
return global()->set(name, len, val, immutable); | |||
} | |||
static VoidParameter* getParam(const char* param) { return global()->get(param); } | |||
static void listParams(int width=79, int nameWidth=10) { global()->list(width, nameWidth); } | |||
protected: | |||
friend class VoidParameter; | |||
friend struct ParameterIterator; | |||
// Name for this Configuration | |||
CharArray name; | |||
static VoidParameter* head; | |||
// - Pointer to first Parameter in this group | |||
VoidParameter* head; | |||
// Pointer to next Configuration in this group | |||
Configuration* _next; | |||
// The process-wide, Global Configuration object | |||
static Configuration* global_; | |||
}; | |||
// -=- VoidParameter | |||
@@ -66,7 +134,7 @@ namespace rfb { | |||
class VoidParameter { | |||
public: | |||
VoidParameter(const char* name_, const char* desc_); | |||
VoidParameter(const char* name_, const char* desc_, Configuration* conf=0); | |||
virtual ~VoidParameter(); | |||
const char* getName() const; | |||
const char* getDescription() const; | |||
@@ -81,8 +149,11 @@ namespace rfb { | |||
virtual void setHasBeenSet(); | |||
bool hasBeenSet(); | |||
VoidParameter* _next; | |||
protected: | |||
friend class Configuration; | |||
friend struct ParameterIterator; | |||
VoidParameter* _next; | |||
bool immutable; | |||
bool _hasBeenSet; | |||
const char* name; | |||
@@ -91,7 +162,7 @@ namespace rfb { | |||
class AliasParameter : public VoidParameter { | |||
public: | |||
AliasParameter(const char* name_, const char* desc_,VoidParameter* param_); | |||
AliasParameter(const char* name_, const char* desc_,VoidParameter* param_, Configuration* conf=0); | |||
virtual bool setParam(const char* value); | |||
virtual bool setParam(); | |||
virtual char* getDefaultStr() const; | |||
@@ -104,7 +175,7 @@ namespace rfb { | |||
class BoolParameter : public VoidParameter { | |||
public: | |||
BoolParameter(const char* name_, const char* desc_, bool v); | |||
BoolParameter(const char* name_, const char* desc_, bool v, Configuration* conf=0); | |||
virtual bool setParam(const char* value); | |||
virtual bool setParam(); | |||
virtual void setParam(bool b); | |||
@@ -119,7 +190,8 @@ namespace rfb { | |||
class IntParameter : public VoidParameter { | |||
public: | |||
IntParameter(const char* name_, const char* desc_, int v); | |||
IntParameter(const char* name_, const char* desc_, int v, | |||
int minValue=INT_MIN, int maxValue=INT_MAX, Configuration* conf=0); | |||
virtual bool setParam(const char* value); | |||
virtual bool setParam(int v); | |||
virtual char* getDefaultStr() const; | |||
@@ -128,13 +200,14 @@ namespace rfb { | |||
protected: | |||
int value; | |||
int def_value; | |||
int minValue, maxValue; | |||
}; | |||
class StringParameter : public VoidParameter { | |||
public: | |||
// StringParameter contains a null-terminated string, which CANNOT | |||
// be Null, and so neither can the default value! | |||
StringParameter(const char* name_, const char* desc_, const char* v); | |||
StringParameter(const char* name_, const char* desc_, const char* v, Configuration* conf=0); | |||
virtual ~StringParameter(); | |||
virtual bool setParam(const char* value); | |||
virtual char* getDefaultStr() const; | |||
@@ -150,13 +223,15 @@ namespace rfb { | |||
class BinaryParameter : public VoidParameter { | |||
public: | |||
BinaryParameter(const char* name_, const char* desc_, const void* v, int l); | |||
BinaryParameter(const char* name_, const char* desc_, const void* v, int l, Configuration* conf=0); | |||
virtual ~BinaryParameter(); | |||
virtual bool setParam(const char* value); | |||
virtual void setParam(const void* v, int l); | |||
virtual char* getDefaultStr() const; | |||
virtual char* getValueStr() const; | |||
// getData() will return length zero if there is no data | |||
// NB: data may be set to zero, OR set to a zero-length buffer | |||
void getData(void** data, int* length) const; | |||
protected: | |||
@@ -166,6 +241,25 @@ namespace rfb { | |||
int def_length; | |||
}; | |||
// -=- ParameterIterator | |||
// Iterates over all the Parameters in a Configuration group. The | |||
// current Parameter is accessed via param, the current Configuration | |||
// via config. The next() method moves on to the next Parameter. | |||
struct ParameterIterator { | |||
ParameterIterator(Configuration* c) : config(c), param(c ? c->head : 0) {} | |||
void next() { | |||
param = param->_next; | |||
while (!param) { | |||
config = config->_next; | |||
if (!config) break; | |||
param = config->head; | |||
} | |||
} | |||
Configuration* config; | |||
VoidParameter* param; | |||
}; | |||
}; | |||
#endif // __RFB_CONFIGURATION_H__ |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -27,9 +27,10 @@ using namespace rfb; | |||
ConnParams::ConnParams() | |||
: majorVersion(0), minorVersion(0), width(0), height(0), useCopyRect(false), | |||
supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(false), supportsLastRect(false), | |||
customCompressLevel(false), compressLevel(6), noJpeg(false), qualityLevel(-1), | |||
name_(0), nEncodings_(0), encodings_(0), | |||
supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(true), | |||
supportsLastRect(false), customCompressLevel(false), compressLevel(6), | |||
noJpeg(false), qualityLevel(-1), | |||
name_(0), nEncodings_(0), encodings_(0), | |||
currentEncoding_(encodingRaw), verStrPos(0) | |||
{ | |||
setName(""); | |||
@@ -88,6 +89,7 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings) | |||
nEncodings_ = nEncodings; | |||
useCopyRect = false; | |||
supportsLocalCursor = false; | |||
supportsDesktopResize = false; | |||
supportsLocalXCursor = false; | |||
supportsLastRect = false; | |||
customCompressLevel = false; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -83,6 +83,7 @@ rdr::U8* Cursor::getBitmap(Pixel* pix0, Pixel* pix1) | |||
{ | |||
bool gotPix0 = false; | |||
bool gotPix1 = false; | |||
*pix0 = *pix1 = 0; | |||
rdr::U8Array source(maskLen()); | |||
memset(source.buf, 0, maskLen()); | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 |
@@ -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 |
@@ -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 | |||
@@ -20,11 +20,6 @@ | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/util.h> | |||
#include <rdr/MemOutStream.h> | |||
#include <time.h> | |||
// *** Shouldn't really link against this - only for ClientWaitTimeMillis | |||
// and IdleTimeout | |||
#include <rfb/ServerCore.h> | |||
#ifdef WIN32 | |||
#define strcasecmp _stricmp | |||
@@ -36,6 +31,9 @@ using namespace rdr; | |||
static LogWriter vlog("HTTPServer"); | |||
const int clientWaitTimeMillis = 20000; | |||
const int idleTimeoutSecs = 5 * 60; | |||
// | |||
// -=- LineReader | |||
@@ -94,7 +92,8 @@ protected: | |||
class rfb::HTTPServer::Session { | |||
public: | |||
Session(network::Socket& s, rfb::HTTPServer& srv) | |||
: contentType(0), line(s.inStream(), 256), sock(s), | |||
: contentType(0), contentLength(-1), lastModified(-1), | |||
line(s.inStream(), 256), sock(s), | |||
server(srv), state(ReadRequestLine), lastActive(time(0)) { | |||
} | |||
~Session() { | |||
@@ -111,6 +110,8 @@ public: | |||
protected: | |||
CharArray uri; | |||
const char* contentType; | |||
int contentLength; | |||
time_t lastModified; | |||
LineReader line; | |||
network::Socket& sock; | |||
rfb::HTTPServer& server; | |||
@@ -140,6 +141,7 @@ void writeLine(OutStream& os, const char* text) { | |||
// - Write an HTTP-compliant response to the client | |||
void | |||
HTTPServer::Session::writeResponse(int result, const char* text) { | |||
char buffer[1024]; | |||
@@ -149,6 +151,19 @@ HTTPServer::Session::writeResponse(int result, const char* text) { | |||
OutStream& os=sock.outStream(); | |||
writeLine(os, buffer); | |||
writeLine(os, "Server: TightVNC/4.0"); | |||
time_t now = time(0); | |||
struct tm* tm = gmtime(&now); | |||
strftime(buffer, 1024, "Date: %a, %d %b %Y %H:%M:%S GMT", tm); | |||
writeLine(os, buffer); | |||
if (lastModified == (time_t)-1 || lastModified == 0) | |||
lastModified = now; | |||
tm = gmtime(&lastModified); | |||
strftime(buffer, 1024, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT", tm); | |||
writeLine(os, buffer); | |||
if (contentLength != -1) { | |||
sprintf(buffer,"Content-Length: %d",contentLength); | |||
writeLine(os, buffer); | |||
} | |||
writeLine(os, "Connection: close"); | |||
os.writeBytes("Content-Type: ", 14); | |||
if (result == 200) { | |||
@@ -247,7 +262,10 @@ HTTPServer::Session::processHTTP() { | |||
{ | |||
CharArray address(sock.getPeerAddress()); | |||
vlog.info("getting %s for %s", uri.buf, address.buf); | |||
InStream* data = server.getFile(uri.buf, &contentType); | |||
contentLength = -1; | |||
lastModified = -1; | |||
InStream* data = server.getFile(uri.buf, &contentType, &contentLength, | |||
&lastModified); | |||
if (!data) | |||
return writeResponse(404); | |||
@@ -277,9 +295,9 @@ HTTPServer::Session::processHTTP() { | |||
int HTTPServer::Session::checkIdleTimeout() { | |||
time_t now = time(0); | |||
int timeout = (lastActive + rfb::Server::idleTimeout) - now; | |||
int timeout = (lastActive + idleTimeoutSecs) - now; | |||
if (timeout > 0) | |||
return timeout * 1000; | |||
return secsToMillis(timeout); | |||
sock.shutdown(); | |||
return 0; | |||
} | |||
@@ -291,28 +309,38 @@ HTTPServer::HTTPServer() { | |||
HTTPServer::~HTTPServer() { | |||
std::list<Session*>::iterator i; | |||
for (i=sessions.begin(); i!=sessions.end(); i++) { | |||
delete (*i)->getSock(); | |||
for (i=sessions.begin(); i!=sessions.end(); i++) | |||
delete *i; | |||
} | |||
} | |||
// -=- SocketServer interface implementation | |||
void | |||
HTTPServer::addClient(network::Socket* sock) { | |||
HTTPServer::addSocket(network::Socket* sock, bool) { | |||
Session* s = new Session(*sock, *this); | |||
if (!s) { | |||
sock->shutdown(); | |||
} else { | |||
sock->inStream().setTimeout(rfb::Server::clientWaitTimeMillis); | |||
sock->outStream().setTimeout(rfb::Server::clientWaitTimeMillis); | |||
sock->inStream().setTimeout(clientWaitTimeMillis); | |||
sock->outStream().setTimeout(clientWaitTimeMillis); | |||
sessions.push_front(s); | |||
} | |||
} | |||
bool | |||
void | |||
HTTPServer::removeSocket(network::Socket* sock) { | |||
std::list<Session*>::iterator i; | |||
for (i=sessions.begin(); i!=sessions.end(); i++) { | |||
if ((*i)->getSock() == sock) { | |||
delete *i; | |||
sessions.erase(i); | |||
return; | |||
} | |||
} | |||
} | |||
void | |||
HTTPServer::processSocketEvent(network::Socket* sock) { | |||
std::list<Session*>::iterator i; | |||
for (i=sessions.begin(); i!=sessions.end(); i++) { | |||
@@ -320,21 +348,16 @@ HTTPServer::processSocketEvent(network::Socket* sock) { | |||
try { | |||
if ((*i)->processHTTP()) { | |||
vlog.info("completed HTTP request"); | |||
delete *i; | |||
sessions.erase(i); | |||
break; | |||
sock->shutdown(); | |||
} | |||
return true; | |||
} catch (rdr::Exception& e) { | |||
vlog.error("untrapped: %s", e.str()); | |||
delete *i; | |||
sessions.erase(i); | |||
break; | |||
sock->shutdown(); | |||
} | |||
return; | |||
} | |||
} | |||
delete sock; | |||
return false; | |||
throw rdr::Exception("invalid Socket in HTTPServer"); | |||
} | |||
void HTTPServer::getSockets(std::list<network::Socket*>* sockets) | |||
@@ -359,7 +382,9 @@ int HTTPServer::checkTimeouts() { | |||
// -=- Default getFile implementation | |||
InStream* | |||
HTTPServer::getFile(const char* name, const char** contentType) { | |||
HTTPServer::getFile(const char* name, const char** contentType, | |||
int* contentLength, time_t* lastModified) | |||
{ | |||
return 0; | |||
} | |||
@@ -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 | |||
@@ -32,6 +32,7 @@ | |||
#include <rfb/UpdateTracker.h> | |||
#include <rfb/Configuration.h> | |||
#include <network/Socket.h> | |||
#include <time.h> | |||
namespace rfb { | |||
@@ -46,32 +47,27 @@ namespace rfb { | |||
virtual ~HTTPServer(); | |||
// -=- Client management | |||
// SocketServer interface | |||
// - Run a client connection on the supplied socket | |||
// addSocket() | |||
// This causes the server to perform HTTP protocol on the | |||
// supplied socket. | |||
// The socket will be closed if protocol initialisation | |||
// fails. | |||
virtual void addClient(network::Socket* sock); | |||
virtual void addSocket(network::Socket* sock, bool outgoing=false); | |||
// -=- Event processing methods | |||
// removeSocket() | |||
// Could clean up socket-specific resources here. | |||
virtual void removeSocket(network::Socket* sock); | |||
// - Process an input event on a particular Socket | |||
// processSocketEvent() | |||
// The platform-specific side of the server implementation calls | |||
// this method whenever data arrives on one of the active | |||
// network sockets. | |||
// The method returns true if the Socket is still in use by the | |||
// server, or false if it is no longer required and should be | |||
// deleted. | |||
// NB: If false is returned then the Socket is deleted and must | |||
// not be accessed again! | |||
virtual bool processSocketEvent(network::Socket* sock); | |||
virtual void processSocketEvent(network::Socket* sock); | |||
// - Check for socket timeouts | |||
// Check for socket timeouts | |||
virtual int checkTimeouts(); | |||
// getSockets() gets a list of sockets. This can be used to generate an | |||
// fd_set for calling select(). | |||
@@ -92,13 +88,15 @@ namespace rfb { | |||
// NB: The contentType is statically allocated by the getFile impl. | |||
// NB: contentType is *guaranteed* to be valid when getFile is called. | |||
virtual rdr::InStream* getFile(const char* name, const char** contentType); | |||
virtual rdr::InStream* getFile(const char* name, const char** contentType, | |||
int* contentLength, time_t* lastModified); | |||
// - guessContentType is passed the name of a file and returns the | |||
// name of an HTTP content type, based on the file's extension. If | |||
// the extension isn't recognised then defType is returned. This can | |||
// be used from getFile to easily default to the supplied contentType, | |||
// or by passing zero in to determine whether a type is recognised or not. | |||
// or by passing zero in to determine whether a type is recognised or | |||
// not. | |||
static const char* guessContentType(const char* name, const char* defType); | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,6 +1,6 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. | |||
* Copyright (C) 2005 Constantin Kaplinsky. 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 |
@@ -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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -19,11 +19,13 @@ | |||
#ifndef __RFB_HOSTNAME_H__ | |||
#define __RFB_HOSTNAME_H__ | |||
#include <stdlib.h> | |||
#include <rdr/Exception.h> | |||
#include <rfb/util.h> | |||
namespace rfb { | |||
void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) { | |||
static void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) { | |||
CharArray portBuf; | |||
CharArray hostBuf; | |||
if (hi[0] == '[') { |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -0,0 +1,40 @@ | |||
/* 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 | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// InputHandler - abstract interface for accepting keyboard & | |||
// pointer input and clipboard data. | |||
// | |||
#ifndef __RFB_INPUTHANDLER_H__ | |||
#define __RFB_INPUTHANDLER_H__ | |||
#include <rdr/types.h> | |||
#include <rfb/Rect.h> | |||
namespace rfb { | |||
class InputHandler { | |||
public: | |||
virtual ~InputHandler() {} | |||
virtual void keyEvent(rdr::U32 key, bool down) {} | |||
virtual void pointerEvent(const Point& pos, int buttonMask) {} | |||
virtual void clientCutText(const char* str, int len) {} | |||
}; | |||
} | |||
#endif |
@@ -0,0 +1,84 @@ | |||
/* 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 | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
#include <stdio.h> | |||
#include <rfb/KeyRemapper.h> | |||
#include <rfb/Configuration.h> | |||
#include <rfb/LogWriter.h> | |||
using namespace rfb; | |||
static LogWriter vlog("KeyRemapper"); | |||
KeyRemapper KeyRemapper::defInstance; | |||
#ifdef __RFB_THREADING_IMPL | |||
static Mutex mappingLock; | |||
#endif | |||
void KeyRemapper::setMapping(const char* m) { | |||
#ifdef __RFB_THREADING_IMPL | |||
Lock l(mappingLock); | |||
#endif | |||
mapping.clear(); | |||
while (m[0]) { | |||
int from, to; | |||
char bidi; | |||
const char* nextComma = strchr(m, ','); | |||
if (!nextComma) | |||
nextComma = m + strlen(m); | |||
if (sscanf(m, "0x%x%c>0x%x", &from, | |||
&bidi, &to) == 3) { | |||
if (bidi != '-' && bidi != '<') | |||
vlog.error("warning: unknown operation %c>, assuming ->", bidi); | |||
mapping[from] = to; | |||
if (bidi == '<') | |||
mapping[to] = from; | |||
} else { | |||
vlog.error("warning: bad mapping %.*s", nextComma-m, m); | |||
} | |||
m = nextComma; | |||
if (nextComma[0]) | |||
m++; | |||
} | |||
} | |||
rdr::U32 KeyRemapper::remapKey(rdr::U32 key) const { | |||
#ifdef __RFB_THREADING_IMPL | |||
Lock l(mappingLock); | |||
#endif | |||
std::map<rdr::U32,rdr::U32>::const_iterator i = mapping.find(key); | |||
if (i != mapping.end()) | |||
return i->second; | |||
return key; | |||
} | |||
class KeyMapParameter : public StringParameter { | |||
public: | |||
KeyMapParameter() | |||
: StringParameter("RemapKeys", "Comma-separated list of incoming keysyms to remap. Mappings are expressed as two hex values, prefixed by 0x, and separated by ->", "") { | |||
setParam(value); | |||
} | |||
bool setParam(const char* v) { | |||
KeyRemapper::defInstance.setMapping(v); | |||
return StringParameter::setParam(v); | |||
} | |||
} defaultParam; | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -15,17 +15,25 @@ | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
#ifndef __RFB_VNCAUTH_H__ | |||
#define __RFB_VNCAUTH_H__ | |||
#ifndef __RFB_KEYREMAPPER_H__ | |||
#define __RFB_KEYREMAPPER_H__ | |||
#include <map> | |||
#include <rdr/types.h> | |||
namespace rfb { | |||
const int vncAuthChallengeSize = 16; | |||
class KeyRemapper { | |||
public: | |||
KeyRemapper(const char* m="") { setMapping(m); } | |||
void setMapping(const char* m); | |||
rdr::U32 remapKey(rdr::U32 key) const; | |||
static KeyRemapper defInstance; | |||
private: | |||
std::map<rdr::U32,rdr::U32> mapping; | |||
}; | |||
}; | |||
void vncAuthEncryptChallenge(rdr::U8* challenge, const char* passwd); | |||
void vncAuthObfuscatePasswd(char* passwd); | |||
void vncAuthUnobfuscatePasswd(char* passwd); | |||
} | |||
#endif | |||
#endif // __RFB_KEYREMAPPER_H__ |
@@ -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 | |||
@@ -53,13 +53,13 @@ void | |||
LogWriter::listLogWriters(int width) { | |||
// *** make this respect width... | |||
LogWriter* current = log_writers; | |||
printf(" "); | |||
fprintf(stderr, " "); | |||
while (current) { | |||
printf("%s", current->m_name); | |||
fprintf(stderr, "%s", current->m_name); | |||
current = current->m_next; | |||
if (current) printf(", "); | |||
if (current) fprintf(stderr, ", "); | |||
} | |||
printf("\n"); | |||
fprintf(stderr, "\n"); | |||
} | |||
LogWriter* LogWriter::log_writers; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -53,6 +53,10 @@ void Logger_File::write(int level, const char *logname, const char *message) | |||
#endif | |||
if (!m_file) { | |||
if (!m_filename) return; | |||
CharArray bakFilename(strlen(m_filename) + 1 + 4); | |||
sprintf(bakFilename.buf, "%s.bak", m_filename); | |||
remove(bakFilename.buf); | |||
rename(m_filename, bakFilename.buf); | |||
m_file = fopen(m_filename, "w+"); | |||
if (!m_file) return; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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,10 +21,12 @@ CXXSRCS = \ | |||
HTTPServer.cxx \ | |||
HextileDecoder.cxx \ | |||
HextileEncoder.cxx \ | |||
KeyRemapper.cxx \ | |||
LogWriter.cxx \ | |||
Logger.cxx \ | |||
Logger_file.cxx \ | |||
Logger_stdio.cxx \ | |||
Password.cxx \ | |||
PixelBuffer.cxx \ | |||
PixelFormat.cxx \ | |||
RREEncoder.cxx \ | |||
@@ -41,6 +43,7 @@ CXXSRCS = \ | |||
ServerCore.cxx \ | |||
SSecurityFactoryStandard.cxx \ | |||
SSecurityVncAuth.cxx \ | |||
Timer.cxx \ | |||
TightDecoder.cxx \ | |||
TightEncoder.cxx \ | |||
TightPalette.cxx \ | |||
@@ -53,8 +56,7 @@ CXXSRCS = \ | |||
ZRLEDecoder.cxx \ | |||
encodings.cxx \ | |||
secTypes.cxx \ | |||
util.cxx \ | |||
vncAuth.cxx | |||
util.cxx | |||
SRCS = d3des.c $(CXXSRCS) | |||
@@ -0,0 +1,77 @@ | |||
/* 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 | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// XXX not thread-safe, because d3des isn't - do we need to worry about this? | |||
// | |||
#include <string.h> | |||
extern "C" { | |||
#include <rfb/d3des.h> | |||
} | |||
#include <rdr/types.h> | |||
#include <rdr/Exception.h> | |||
#include <rfb/Password.h> | |||
using namespace rfb; | |||
static unsigned char d3desObfuscationKey[] = {23,82,107,6,35,78,88,7}; | |||
PlainPasswd::PlainPasswd() {} | |||
PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { | |||
} | |||
PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { | |||
if (obfPwd.length < 8) | |||
throw rdr::Exception("bad obfuscated password length"); | |||
deskey(d3desObfuscationKey, DE1); | |||
des((rdr::U8*)obfPwd.buf, (rdr::U8*)buf); | |||
buf[8] = 0; | |||
} | |||
PlainPasswd::~PlainPasswd() { | |||
replaceBuf(0); | |||
} | |||
void PlainPasswd::replaceBuf(char* b) { | |||
if (buf) | |||
memset(buf, 0, strlen(buf)); | |||
CharArray::replaceBuf(b); | |||
} | |||
ObfuscatedPasswd::ObfuscatedPasswd() : length(0) { | |||
} | |||
ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) { | |||
} | |||
ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) { | |||
int l = strlen(plainPwd.buf), i; | |||
for (i=0; i<8; i++) | |||
buf[i] = i<l ? plainPwd.buf[i] : 0; | |||
deskey(d3desObfuscationKey, EN0); | |||
des((rdr::U8*)buf, (rdr::U8*)buf); | |||
} | |||
ObfuscatedPasswd::~ObfuscatedPasswd() { | |||
if (buf) | |||
memset(buf, 0, length); | |||
} |
@@ -0,0 +1,46 @@ | |||
/* 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 | |||
* (at your option) any later version. | |||
* | |||
* This software is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
#ifndef __RFB_PASSWORD_H__ | |||
#define __RFB_PASSWORD_H__ | |||
#include <rfb/util.h> | |||
namespace rfb { | |||
class ObfuscatedPasswd; | |||
class PlainPasswd : public CharArray { | |||
public: | |||
PlainPasswd(); | |||
PlainPasswd(char* pwd); | |||
PlainPasswd(const ObfuscatedPasswd& obfPwd); | |||
~PlainPasswd(); | |||
void replaceBuf(char* b); | |||
}; | |||
class ObfuscatedPasswd : public CharArray { | |||
public: | |||
ObfuscatedPasswd(); | |||
ObfuscatedPasswd(int l); | |||
ObfuscatedPasswd(const PlainPasswd& plainPwd); | |||
~ObfuscatedPasswd(); | |||
int length; | |||
}; | |||
} | |||
#endif |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 |
@@ -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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 |
@@ -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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 |
@@ -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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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,11 +21,16 @@ | |||
#ifndef __RFB_RECT_INCLUDED__ | |||
#define __RFB_RECT_INCLUDED__ | |||
#ifndef vncmin | |||
#define vncmin(a,b) (((a) < (b)) ? (a) : (b)) | |||
// Some platforms (e.g. Windows) include max() and min() macros in their | |||
// standard headers, but they are also standard C++ template functions, so some | |||
// C++ headers will undefine them. So we steer clear of the names min and max | |||
// and define __rfbmin and __rfbmax instead. | |||
#ifndef __rfbmax | |||
#define __rfbmax(a,b) (((a) > (b)) ? (a) : (b)) | |||
#endif | |||
#ifndef vncmax | |||
#define vncmax(a,b) (((a) > (b)) ? (a) : (b)) | |||
#ifndef __rfbmin | |||
#define __rfbmin(a,b) (((a) < (b)) ? (a) : (b)) | |||
#endif | |||
namespace rfb { | |||
@@ -69,20 +74,20 @@ namespace rfb { | |||
} | |||
inline Rect intersect(const Rect &r) const { | |||
Rect result; | |||
result.tl.x = vncmax(tl.x, r.tl.x); | |||
result.tl.y = vncmax(tl.y, r.tl.y); | |||
result.br.x = vncmax(vncmin(br.x, r.br.x), result.tl.x); | |||
result.br.y = vncmax(vncmin(br.y, r.br.y), result.tl.y); | |||
result.tl.x = __rfbmax(tl.x, r.tl.x); | |||
result.tl.y = __rfbmax(tl.y, r.tl.y); | |||
result.br.x = __rfbmax(__rfbmin(br.x, r.br.x), result.tl.x); | |||
result.br.y = __rfbmax(__rfbmin(br.y, r.br.y), result.tl.y); | |||
return result; | |||
} | |||
inline Rect union_boundary(const Rect &r) const { | |||
if (r.is_empty()) return *this; | |||
if (is_empty()) return r; | |||
Rect result; | |||
result.tl.x = vncmin(tl.x, r.tl.x); | |||
result.tl.y = vncmin(tl.y, r.tl.y); | |||
result.br.x = vncmax(br.x, r.br.x); | |||
result.br.y = vncmax(br.y, r.br.y); | |||
result.tl.x = __rfbmin(tl.x, r.tl.x); | |||
result.tl.y = __rfbmin(tl.y, r.tl.y); | |||
result.br.x = __rfbmax(br.x, r.br.x); | |||
result.br.y = __rfbmax(br.y, r.br.y); | |||
return result; | |||
} | |||
inline Rect translate(const Point &p) const { |
@@ -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 |
@@ -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 |
@@ -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::AccessNoQuery = 0x0400; | |||
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 @@ void SConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_) | |||
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 @@ void SConnection::processVersionMsg() | |||
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 @@ void SConnection::processSecurityTypeMsg() | |||
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; | |||
} | |||
if (i == nSecTypes) { | |||
char msg[256]; | |||
sprintf(msg,"Security type %s(%d) from client not supported", | |||
secTypeName(secType),secType); | |||
throwConnFailedException(msg); | |||
try { | |||
state_ = RFBSTATE_SECURITY; | |||
security = securityFactory->getSSecurity(secType, reverseConnection); | |||
} catch (rdr::Exception& e) { | |||
throwConnFailedException(e.str()); | |||
} | |||
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::authSuccess() | |||
{ | |||
} | |||
void SConnection::authFailure() | |||
{ | |||
} | |||
void SConnection::queryConnection(const char* userName) | |||
{ | |||
approveConnection(true); | |||
@@ -298,7 +281,6 @@ void SConnection::approveConnection(bool accept, const char* reason) | |||
authSuccess(); | |||
} else { | |||
state_ = RFBSTATE_INVALID; | |||
authFailure(); | |||
throw AuthFailureException(reason); | |||
} | |||
} |
@@ -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 | |||
@@ -26,6 +26,7 @@ | |||
#include <rdr/InStream.h> | |||
#include <rdr/OutStream.h> | |||
#include <rfb/SMsgHandler.h> | |||
#include <rfb/SSecurity.h> | |||
namespace rfb { | |||
@@ -36,7 +37,7 @@ namespace rfb { | |||
class SConnection : public SMsgHandler { | |||
public: | |||
SConnection(); | |||
SConnection(SSecurityFactory* sf, bool reverseConnection_); | |||
virtual ~SConnection(); | |||
// Methods to initialise the connection | |||
@@ -49,10 +50,6 @@ namespace rfb { | |||
// (i.e. SConnection will not delete them). | |||
void setStreams(rdr::InStream* is, rdr::OutStream* os); | |||
// addSecType() should be called once for each security type which the | |||
// server supports to this client. | |||
void addSecType(rdr::U8 secType); | |||
// initialiseProtocol() should be called once the streams and security | |||
// types are set. Subsequently, processMsg() should be called whenever | |||
// there is data to read on the InStream. | |||
@@ -78,19 +75,9 @@ namespace rfb { | |||
// to deal with unknown/bogus viewer protocol numbers. | |||
virtual void versionReceived(); | |||
// getSSecurity() gets the SSecurity object for the given type. The type | |||
// is guaranteed to be one of the secTypes passed in to addSecType(). The | |||
// SSecurity object's destroy() method will be called by the SConnection | |||
// from its destructor. | |||
virtual SSecurity* getSSecurity(int secType)=0; | |||
// authSuccess() is called when authentication has succeeded. | |||
virtual void authSuccess(); | |||
// authFailure() is called when authentication has failed. This method is | |||
// not normally overridden since an exception is thrown anyway. | |||
virtual void authFailure(); | |||
// queryConnection() is called when authentication has succeeded, but | |||
// before informing the client. It can be overridden to query a local user | |||
// to accept the incoming connection, for example. The userName argument | |||
@@ -178,7 +165,8 @@ namespace rfb { | |||
stateEnum state() { return state_; } | |||
// ssecurity() returns a pointer to this connection's SSecurity object, if any | |||
// ssecurity() returns a pointer to this connection's SSecurity object, if | |||
// any | |||
const SSecurity* ssecurity() const { return security; } | |||
protected: | |||
@@ -186,7 +174,6 @@ namespace rfb { | |||
bool readyForSetColourMapEntries; | |||
private: | |||
void processVersionMsg(); | |||
void processSecurityTypeMsg(); | |||
void processSecurityMsg(); | |||
@@ -197,11 +184,10 @@ namespace rfb { | |||
rdr::OutStream* os; | |||
SMsgReader* reader_; | |||
SMsgWriter* writer_; | |||
enum { maxSecTypes = 8 }; | |||
int nSecTypes; | |||
rdr::U8 secTypes[maxSecTypes]; | |||
SSecurity* security; | |||
SSecurityFactory* securityFactory; | |||
stateEnum state_; | |||
bool reverseConnection; | |||
}; | |||
} | |||
#endif |
@@ -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 | |||
@@ -39,13 +39,14 @@ | |||
#include <rfb/PixelBuffer.h> | |||
#include <rfb/VNCServer.h> | |||
#include <rfb/InputHandler.h> | |||
#include <rfb/Exception.h> | |||
namespace rfb { | |||
class VNCServer; | |||
class SDesktop { | |||
class SDesktop : public InputHandler { | |||
public: | |||
// start() is called by the server when the first client authenticates | |||
// successfully, and can be used to begin any expensive tasks which are not | |||
@@ -62,13 +63,6 @@ namespace rfb { | |||
virtual void stop() {} | |||
// pointerEvent(), keyEvent() and clientCutText() are called in response to | |||
// the relevant RFB protocol messages from clients. | |||
virtual void pointerEvent(const Point& pos, rdr::U8 buttonmask) {} | |||
virtual void keyEvent(rdr::U32 key, bool down) {} | |||
virtual void clientCutText(const char* str, int len) {} | |||
// framebufferUpdateRequest() is called to let the desktop know that at | |||
// least one client has become ready for an update. Desktops can check | |||
// whether there are clients ready at any time by calling the VNCServer's | |||
@@ -81,6 +75,10 @@ namespace rfb { | |||
virtual Point getFbSize() = 0; | |||
// InputHandler interface | |||
// pointerEvent(), keyEvent() and clientCutText() are called in response to | |||
// the relevant RFB protocol messages from clients. | |||
// See InputHandler for method signatures. | |||
protected: | |||
virtual ~SDesktop() {} | |||
}; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -47,18 +47,6 @@ void SMsgHandler::framebufferUpdateRequest(const Rect& r, bool incremental) | |||
{ | |||
} | |||
void SMsgHandler::keyEvent(rdr::U32 key, bool down) | |||
{ | |||
} | |||
void SMsgHandler::pointerEvent(int x, int y, int buttonMask) | |||
{ | |||
} | |||
void SMsgHandler::clientCutText(const char* str, int len) | |||
{ | |||
} | |||
void SMsgHandler::supportsLocalCursor() | |||
{ | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -25,13 +25,13 @@ | |||
#include <rdr/types.h> | |||
#include <rfb/PixelFormat.h> | |||
#include <rfb/ConnParams.h> | |||
#include <rfb/Rect.h> | |||
#include <rfb/InputHandler.h> | |||
namespace rdr { class InStream; } | |||
namespace rfb { | |||
class SMsgHandler { | |||
class SMsgHandler : public InputHandler { | |||
public: | |||
SMsgHandler(); | |||
virtual ~SMsgHandler(); | |||
@@ -46,9 +46,9 @@ namespace rfb { | |||
virtual void setPixelFormat(const PixelFormat& pf); | |||
virtual void setEncodings(int nEncodings, rdr::U32* encodings); | |||
virtual void framebufferUpdateRequest(const Rect& r, bool incremental); | |||
virtual void keyEvent(rdr::U32 key, bool down); | |||
virtual void pointerEvent(int x, int y, int buttonMask); | |||
virtual void clientCutText(const char* str, int len); | |||
// InputHandler interface | |||
// The InputHandler methods will be called for the corresponding messages. | |||
// supportsLocalCursor() is called whenever the status of | |||
// cp.supportsLocalCursor has changed. At the moment this happens on a |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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,9 +21,12 @@ | |||
#include <rfb/util.h> | |||
#include <rfb/SMsgHandler.h> | |||
#include <rfb/SMsgReader.h> | |||
#include <rfb/Configuration.h> | |||
using namespace rfb; | |||
static IntParameter maxCutText("MaxCutText", "Maximum permitted length of an incoming clipboard update", 256*1024); | |||
SMsgReader::SMsgReader(SMsgHandler* handler_, rdr::InStream* is_) | |||
: handler(handler_), is(is_) | |||
{ | |||
@@ -33,16 +36,11 @@ SMsgReader::~SMsgReader() | |||
{ | |||
} | |||
void SMsgReader::endMsg() | |||
{ | |||
} | |||
void SMsgReader::readSetPixelFormat() | |||
{ | |||
is->skip(3); | |||
PixelFormat pf; | |||
pf.read(is); | |||
endMsg(); | |||
handler->setPixelFormat(pf); | |||
} | |||
@@ -50,12 +48,10 @@ void SMsgReader::readSetEncodings() | |||
{ | |||
is->skip(1); | |||
int nEncodings = is->readU16(); | |||
rdr::U32* encodings = new rdr::U32[nEncodings]; | |||
rdr::U32Array encodings(nEncodings); | |||
for (int i = 0; i < nEncodings; i++) | |||
encodings[i] = is->readU32(); | |||
endMsg(); | |||
handler->setEncodings(nEncodings, encodings); | |||
delete [] encodings; | |||
encodings.buf[i] = is->readU32(); | |||
handler->setEncodings(nEncodings, encodings.buf); | |||
} | |||
void SMsgReader::readFramebufferUpdateRequest() | |||
@@ -65,7 +61,6 @@ void SMsgReader::readFramebufferUpdateRequest() | |||
int y = is->readU16(); | |||
int w = is->readU16(); | |||
int h = is->readU16(); | |||
endMsg(); | |||
handler->framebufferUpdateRequest(Rect(x, y, x+w, y+h), inc); | |||
} | |||
@@ -74,7 +69,6 @@ void SMsgReader::readKeyEvent() | |||
bool down = is->readU8(); | |||
is->skip(2); | |||
rdr::U32 key = is->readU32(); | |||
endMsg(); | |||
handler->keyEvent(key, down); | |||
} | |||
@@ -83,8 +77,7 @@ void SMsgReader::readPointerEvent() | |||
int mask = is->readU8(); | |||
int x = is->readU16(); | |||
int y = is->readU16(); | |||
endMsg(); | |||
handler->pointerEvent(x, y, mask); | |||
handler->pointerEvent(Point(x, y), mask); | |||
} | |||
@@ -92,7 +85,7 @@ void SMsgReader::readClientCutText() | |||
{ | |||
is->skip(3); | |||
int len = is->readU32(); | |||
if (len > 256*1024) { | |||
if (len > maxCutText) { | |||
is->skip(len); | |||
fprintf(stderr,"cut text too long (%d bytes) - ignoring\n",len); | |||
return; | |||
@@ -100,6 +93,5 @@ void SMsgReader::readClientCutText() | |||
CharArray ca(len+1); | |||
ca.buf[len] = 0; | |||
is->readBytes(ca.buf, len); | |||
endMsg(); | |||
handler->clientCutText(ca.buf, len); | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -46,7 +46,6 @@ namespace rfb { | |||
virtual void readKeyEvent(); | |||
virtual void readPointerEvent(); | |||
virtual void readClientCutText(); | |||
virtual void endMsg(); | |||
SMsgReader(SMsgHandler* handler, rdr::InStream* is); | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -36,7 +36,6 @@ SMsgReaderV3::~SMsgReaderV3() | |||
void SMsgReaderV3::readClientInit() | |||
{ | |||
bool shared = is->readU8(); | |||
endMsg(); | |||
handler->clientInit(shared); | |||
} | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -176,11 +176,6 @@ void SMsgWriter::writeCopyRect(const Rect& r, int srcX, int srcY) | |||
endRect(); | |||
} | |||
void SMsgWriter::setOutStream(rdr::OutStream* os_) | |||
{ | |||
os = os_; | |||
} | |||
rdr::U8* SMsgWriter::getImageBuf(int required, int requested, int* nPixels) | |||
{ | |||
int requiredBytes = required * (cp->pf().bpp / 8); |
@@ -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 | |||
@@ -80,8 +80,8 @@ namespace rfb { | |||
// in response to the writeSetCursorCallback() callback. For a V3 writer | |||
// this will happen when the next update is sent. | |||
virtual void cursorChange(WriteSetCursorCallback* cb)=0; | |||
virtual void writeSetCursor(int width, int height, int hotspotX, | |||
int hotspotY, void* data, void* mask)=0; | |||
virtual void writeSetCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask)=0; | |||
virtual void writeSetXCursor(int width, int height, int hotspotX, | |||
int hotspotY, void* data, void* mask)=0; | |||
@@ -127,9 +127,6 @@ namespace rfb { | |||
virtual void startRect(const Rect& r, unsigned int enc)=0; | |||
virtual void endRect()=0; | |||
// setOutStream() changes the OutStream on the fly. | |||
virtual void setOutStream(rdr::OutStream* os); | |||
ConnParams* getConnParams() { return cp; } | |||
rdr::OutStream* getOutStream() { return os; } | |||
rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0); |
@@ -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 | |||
@@ -69,14 +69,14 @@ void SMsgWriterV3::cursorChange(WriteSetCursorCallback* cb) | |||
wsccb = cb; | |||
} | |||
void SMsgWriterV3::writeSetCursor(int width, int height, int hotspotX, | |||
int hotspotY, void* data, void* mask) | |||
void SMsgWriterV3::writeSetCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask) | |||
{ | |||
if (!wsccb) return; | |||
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) | |||
throw Exception("SMsgWriterV3::writeSetCursor: nRects out of sync"); | |||
os->writeS16(hotspotX); | |||
os->writeS16(hotspotY); | |||
os->writeS16(hotspot.x); | |||
os->writeS16(hotspot.y); | |||
os->writeU16(width); | |||
os->writeU16(height); | |||
os->writeU32(pseudoEncodingCursor); | |||
@@ -138,6 +138,8 @@ void SMsgWriterV3::writeFramebufferUpdateStart() | |||
void SMsgWriterV3::writeFramebufferUpdateEnd() | |||
{ | |||
if (needSetDesktopSize) { | |||
if (!cp->supportsDesktopResize) | |||
throw Exception("Client does not support desktop resize"); | |||
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) | |||
throw Exception("SMsgWriterV3 setDesktopSize: nRects out of sync"); | |||
os->writeS16(0); | |||
@@ -193,9 +195,3 @@ void SMsgWriterV3::endRect() | |||
rectsSent[currentEncoding]++; | |||
} | |||
} | |||
void SMsgWriterV3::setOutStream(rdr::OutStream* os_) | |||
{ | |||
SMsgWriter::setOutStream(os_); | |||
realOS = os; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -33,8 +33,8 @@ namespace rfb { | |||
virtual void endMsg(); | |||
virtual bool writeSetDesktopSize(); | |||
virtual void cursorChange(WriteSetCursorCallback* cb); | |||
virtual void writeSetCursor(int width, int height, int hotspotX, | |||
int hotspotY, void* data, void* mask); | |||
virtual void writeSetCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask); | |||
virtual void writeSetXCursor(int width, int height, int hotspotX, | |||
int hotspotY, void* data, void* mask); | |||
virtual void writeFramebufferUpdateStart(int nRects); | |||
@@ -44,8 +44,6 @@ namespace rfb { | |||
virtual void startRect(const Rect& r, unsigned int encoding); | |||
virtual void endRect(); | |||
virtual void setOutStream(rdr::OutStream* os); | |||
private: | |||
rdr::MemOutStream* updateOS; | |||
rdr::OutStream* realOS; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -18,10 +18,16 @@ | |||
// | |||
// SSecurity - class on the server side for handling security handshaking. A | |||
// derived class for a particular security type overrides the processMsg() | |||
// method. processMsg() is called first when the security type has been | |||
// decided on, and will keep being called whenever there is data to read from | |||
// the client until either it returns false, indicating authentication/security | |||
// failure, or it returns with done set to true, to indicate success. | |||
// method. | |||
// processMsg() is called first when the security type has been decided on, and | |||
// will keep being called whenever there is data to read from the client. It | |||
// should return false when it needs more data, or true when the connection has | |||
// been successfully authenticated. In the event of authentication failure an | |||
// AuthFailureException should be thrown - this will result in a "failed" | |||
// security result being sent to the client with the str() from the exception | |||
// being sent as the reason. Any other type of failure should be indicated by | |||
// some other kind of exception which will cause the connection to be aborted. | |||
// | |||
// processMsg() must never block (or at least must never block until the client | |||
// has been authenticated) - this is to prevent denial of service attacks. | |||
@@ -33,13 +39,13 @@ | |||
// getType() should return the secType value corresponding to the SSecurity | |||
// implementation. | |||
// | |||
// failureMessage_.buf can be set to a string which will be passed to the client | |||
// if processMsg returns false, to indicate the reason for the failure. | |||
#ifndef __RFB_SSECURITY_H__ | |||
#define __RFB_SSECURITY_H__ | |||
#include <rdr/types.h> | |||
#include <rfb/util.h> | |||
#include <list> | |||
namespace rfb { | |||
@@ -48,7 +54,7 @@ namespace rfb { | |||
class SSecurity { | |||
public: | |||
virtual ~SSecurity() {} | |||
virtual bool processMsg(SConnection* sc, bool* done)=0; | |||
virtual bool processMsg(SConnection* sc)=0; | |||
virtual void destroy() { delete this; } | |||
virtual int getType() const = 0; | |||
@@ -57,20 +63,21 @@ namespace rfb { | |||
// necessary. Null may be returned to indicate that there is no user name | |||
// for this security type. | |||
virtual const char* getUserName() const = 0; | |||
virtual const char* failureMessage() {return failureMessage_.buf;} | |||
protected: | |||
CharArray failureMessage_; | |||
}; | |||
// SSecurityFactory creates new SSecurity instances for | |||
// particular security types. | |||
// The instances must be destroyed by calling destroy() | |||
// on them when done. | |||
// getSecTypes returns a list of the security types that are both configured | |||
// and actually supported. Which configuration is considered depends on the | |||
// reverseConnection parameter. | |||
class SSecurityFactory { | |||
public: | |||
virtual ~SSecurityFactory() {} | |||
virtual SSecurity* getSSecurity(int secType, bool noAuth=false)=0; | |||
virtual SSecurity* getSSecurity(rdr::U8 secType, bool noAuth=false)=0; | |||
virtual void getSecTypes(std::list<rdr::U8>* secTypes, | |||
bool reverseConnection) = 0; | |||
}; | |||
} |
@@ -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 | |||
@@ -25,77 +25,104 @@ | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/Exception.h> | |||
#include <rfb/SSecurityFactoryStandard.h> | |||
#include <rfb/Password.h> | |||
using namespace rfb; | |||
static LogWriter vlog("SSecurityFactoryStandard"); | |||
VncAuthPasswdParameter* SSecurityFactoryStandard::vncAuthPasswd = 0; | |||
StringParameter SSecurityFactoryStandard::sec_types | |||
("SecurityTypes", | |||
"Specify which security scheme to use for incoming connections (None, VncAuth)", | |||
"VncAuth"); | |||
StringParameter SSecurityFactoryStandard::rev_sec_types | |||
("ReverseSecurityTypes", | |||
"Specify encryption scheme to use for reverse connections (None)", | |||
"None"); | |||
StringParameter SSecurityFactoryStandard::vncAuthPasswdFile | |||
("PasswordFile", "Password file for VNC authentication", ""); | |||
VncAuthPasswdParameter SSecurityFactoryStandard::vncAuthPasswd | |||
("Password", "Obfuscated binary encoding of the password which clients must supply to " | |||
"access the server", &SSecurityFactoryStandard::vncAuthPasswdFile); | |||
SSecurity* SSecurityFactoryStandard::getSSecurity(int secType, bool noAuth) { | |||
SSecurity* SSecurityFactoryStandard::getSSecurity(rdr::U8 secType, bool reverseConnection) { | |||
switch (secType) { | |||
case secTypeNone: return new SSecurityNone(); | |||
case secTypeNone: return new SSecurityNone(); | |||
case secTypeVncAuth: | |||
if (!vncAuthPasswd) | |||
throw rdr::Exception("No VncAuthPasswdParameter defined!"); | |||
return new SSecurityVncAuth(vncAuthPasswd); | |||
return new SSecurityVncAuth(&vncAuthPasswd); | |||
default: | |||
throw Exception("Unsupported secType?"); | |||
throw Exception("Security type not supported"); | |||
} | |||
} | |||
VncAuthPasswdParameter::VncAuthPasswdParameter() { | |||
if (SSecurityFactoryStandard::vncAuthPasswd) | |||
throw rdr::Exception("duplicate VncAuthPasswdParameter!"); | |||
SSecurityFactoryStandard::vncAuthPasswd = this; | |||
} | |||
VncAuthPasswdConfigParameter::VncAuthPasswdConfigParameter() | |||
: passwdParam("Password", | |||
"Obfuscated binary encoding of the password which clients must supply to " | |||
"access the server", 0, 0) { | |||
void SSecurityFactoryStandard::getSecTypes(std::list<rdr::U8>* secTypes, bool reverseConnection) { | |||
CharArray secTypesStr; | |||
if (reverseConnection) | |||
secTypesStr.buf = rev_sec_types.getData(); | |||
else | |||
secTypesStr.buf = sec_types.getData(); | |||
std::list<int> configured = parseSecTypes(secTypesStr.buf); | |||
std::list<int>::iterator i; | |||
for (i=configured.begin(); i!=configured.end(); i++) { | |||
if (isSecTypeSupported(*i)) | |||
secTypes->push_back(*i); | |||
} | |||
} | |||
char* VncAuthPasswdConfigParameter::getVncAuthPasswd() { | |||
CharArray obfuscated; | |||
int len; | |||
passwdParam.getData((void**)&obfuscated.buf, &len); | |||
printf("vnc password len=%d\n", len); // *** | |||
if (len == 8) { | |||
CharArray password(9); | |||
memcpy(password.buf, obfuscated.buf, 8); | |||
vncAuthUnobfuscatePasswd(password.buf); | |||
return password.takeBuf(); | |||
bool SSecurityFactoryStandard::isSecTypeSupported(rdr::U8 secType) { | |||
switch (secType) { | |||
case secTypeNone: | |||
case secTypeVncAuth: | |||
return true; | |||
default: | |||
return false; | |||
} | |||
return 0; | |||
} | |||
VncAuthPasswdFileParameter::VncAuthPasswdFileParameter() | |||
: param("PasswordFile", "Password file for VNC authentication", "") { | |||
VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name, | |||
const char* desc, | |||
StringParameter* passwdFile_) | |||
: BinaryParameter(name, desc, 0, 0), passwdFile(passwdFile_) { | |||
} | |||
char* VncAuthPasswdFileParameter::getVncAuthPasswd() { | |||
CharArray fname(param.getData()); | |||
if (!fname.buf[0]) { | |||
vlog.error("passwordFile parameter not set"); | |||
return 0; | |||
} | |||
FILE* fp = fopen(fname.buf, "r"); | |||
if (!fp) { | |||
vlog.error("opening password file '%s' failed",fname.buf); | |||
return 0; | |||
char* VncAuthPasswdParameter::getVncAuthPasswd() { | |||
ObfuscatedPasswd obfuscated; | |||
getData((void**)&obfuscated.buf, &obfuscated.length); | |||
if (obfuscated.length == 0) { | |||
if (passwdFile) { | |||
CharArray fname(passwdFile->getData()); | |||
if (!fname.buf[0]) { | |||
vlog.info("neither %s nor %s params set", getName(), passwdFile->getName()); | |||
return 0; | |||
} | |||
FILE* fp = fopen(fname.buf, "r"); | |||
if (!fp) { | |||
vlog.error("opening password file '%s' failed",fname.buf); | |||
return 0; | |||
} | |||
vlog.debug("reading password file"); | |||
obfuscated.buf = new char[128]; | |||
obfuscated.length = fread(obfuscated.buf, 1, 128, fp); | |||
fclose(fp); | |||
} else { | |||
vlog.info("%s parameter not set", getName()); | |||
} | |||
} | |||
CharArray passwd(9); | |||
int len = fread(passwd.buf, 1, 9, fp); | |||
fclose(fp); | |||
if (len != 8) { | |||
vlog.error("password file '%s' is the wrong length",fname.buf); | |||
try { | |||
PlainPasswd password(obfuscated); | |||
return password.takeBuf(); | |||
} catch (...) { | |||
return 0; | |||
} | |||
vncAuthUnobfuscatePasswd(passwd.buf); | |||
return passwd.takeBuf(); | |||
} | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -44,31 +44,24 @@ | |||
namespace rfb { | |||
class VncAuthPasswdParameter : public VncAuthPasswdGetter { | |||
public: | |||
VncAuthPasswdParameter(); | |||
virtual ~VncAuthPasswdParameter() {} | |||
}; | |||
class SSecurityFactoryStandard : public SSecurityFactory { | |||
class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter { | |||
public: | |||
virtual SSecurity* getSSecurity(int secType, bool noAuth); | |||
static VncAuthPasswdParameter* vncAuthPasswd; | |||
}; | |||
class VncAuthPasswdConfigParameter : public VncAuthPasswdParameter { | |||
public: | |||
VncAuthPasswdConfigParameter(); | |||
VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_); | |||
virtual char* getVncAuthPasswd(); | |||
protected: | |||
BinaryParameter passwdParam; | |||
StringParameter* passwdFile; | |||
}; | |||
class VncAuthPasswdFileParameter : public VncAuthPasswdParameter { | |||
class SSecurityFactoryStandard : public SSecurityFactory { | |||
public: | |||
VncAuthPasswdFileParameter(); | |||
virtual char* getVncAuthPasswd(); | |||
StringParameter param; | |||
virtual SSecurity* getSSecurity(rdr::U8 secType, bool reverse); | |||
virtual void getSecTypes(std::list<rdr::U8>* secTypes, bool reverse); | |||
static StringParameter sec_types; | |||
static StringParameter rev_sec_types; | |||
static StringParameter vncAuthPasswdFile; | |||
static VncAuthPasswdParameter vncAuthPasswd; | |||
protected: | |||
virtual bool isSecTypeSupported(rdr::U8 secType); | |||
}; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -28,9 +28,7 @@ namespace rfb { | |||
class SSecurityNone : public SSecurity { | |||
public: | |||
virtual bool processMsg(SConnection* sc, bool* done) { | |||
*done = true; return true; | |||
} | |||
virtual bool processMsg(SConnection* sc) { return true; } | |||
virtual int getType() const {return secTypeNone;} | |||
virtual const char* getUserName() const {return 0;} | |||
}; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -18,20 +18,27 @@ | |||
// | |||
// SSecurityVncAuth | |||
// | |||
// XXX not thread-safe, because d3des isn't - do we need to worry about this? | |||
// | |||
#include <rfb/SSecurityVncAuth.h> | |||
#include <rdr/RandomStream.h> | |||
#include <rfb/SConnection.h> | |||
#include <rfb/vncAuth.h> | |||
#include <rfb/Password.h> | |||
#include <rfb/Configuration.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/util.h> | |||
#include <rfb/Exception.h> | |||
#include <string.h> | |||
#include <stdio.h> | |||
extern "C" { | |||
#include <rfb/d3des.h> | |||
} | |||
using namespace rfb; | |||
static LogWriter vlog("VncAuth"); | |||
static LogWriter vlog("SVncAuth"); | |||
SSecurityVncAuth::SSecurityVncAuth(VncAuthPasswdGetter* pg_) | |||
@@ -39,9 +46,8 @@ SSecurityVncAuth::SSecurityVncAuth(VncAuthPasswdGetter* pg_) | |||
{ | |||
} | |||
bool SSecurityVncAuth::processMsg(SConnection* sc, bool* done) | |||
bool SSecurityVncAuth::processMsg(SConnection* sc) | |||
{ | |||
*done = false; | |||
rdr::InStream* is = sc->getInStream(); | |||
rdr::OutStream* os = sc->getOutStream(); | |||
@@ -51,33 +57,31 @@ bool SSecurityVncAuth::processMsg(SConnection* sc, bool* done) | |||
os->writeBytes(challenge, vncAuthChallengeSize); | |||
os->flush(); | |||
sentChallenge = true; | |||
return true; | |||
return false; | |||
} | |||
if (responsePos >= vncAuthChallengeSize) return false; | |||
while (is->checkNoWait(1) && responsePos < vncAuthChallengeSize) { | |||
while (responsePos < vncAuthChallengeSize && is->checkNoWait(1)) | |||
response[responsePos++] = is->readU8(); | |||
} | |||
if (responsePos < vncAuthChallengeSize) return true; | |||
if (responsePos < vncAuthChallengeSize) return false; | |||
CharArray passwd(pg->getVncAuthPasswd()); | |||
PlainPasswd passwd(pg->getVncAuthPasswd()); | |||
// Beyond this point, there is no more VNCAuth protocol to perform. | |||
*done = true; | |||
if (!passwd.buf) | |||
throw AuthFailureException("No password configured for VNC Auth"); | |||
if (!passwd.buf) { | |||
failureMessage_.buf = strDup("No password configured for VNC Auth"); | |||
vlog.error(failureMessage_.buf); | |||
return false; | |||
} | |||
vncAuthEncryptChallenge(challenge, passwd.buf); | |||
memset(passwd.buf, 0, strlen(passwd.buf)); | |||
// 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 (memcmp(challenge, response, vncAuthChallengeSize) != 0) { | |||
return false; | |||
} | |||
// Check the actual response | |||
if (memcmp(challenge, response, vncAuthChallengeSize) != 0) | |||
throw AuthFailureException(); | |||
return true; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -26,7 +26,7 @@ | |||
#include <rfb/SSecurity.h> | |||
#include <rfb/secTypes.h> | |||
#include <rfb/vncAuth.h> | |||
#include <rdr/types.h> | |||
namespace rfb { | |||
@@ -40,10 +40,11 @@ namespace rfb { | |||
class SSecurityVncAuth : public SSecurity { | |||
public: | |||
SSecurityVncAuth(VncAuthPasswdGetter* pg); | |||
virtual bool processMsg(SConnection* sc, bool* done); | |||
virtual bool processMsg(SConnection* sc); | |||
virtual int getType() const {return secTypeVncAuth;} | |||
virtual const char* getUserName() const {return 0;} | |||
private: | |||
enum {vncAuthChallengeSize = 16}; | |||
rdr::U8 challenge[vncAuthChallengeSize]; | |||
rdr::U8 response[vncAuthChallengeSize]; | |||
bool sentChallenge; |
@@ -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 | |||
@@ -24,38 +24,29 @@ | |||
#include <string.h> | |||
#include <rfb/util.h> | |||
#include <rfb/ServerCore.h> | |||
#include <rfb/vncAuth.h> | |||
rfb::IntParameter rfb::Server::idleTimeout | |||
("IdleTimeout", | |||
"The number of seconds after which an idle VNC connection will be dropped", | |||
0); | |||
"The number of seconds after which an idle VNC connection will be dropped " | |||
"(zero means no timeout)", | |||
0, 0); | |||
rfb::IntParameter rfb::Server::maxDisconnectionTime | |||
("MaxDisconnectionTime", | |||
"Terminate when no client has been connected for s seconds", | |||
0); | |||
0, 0); | |||
rfb::IntParameter rfb::Server::maxConnectionTime | |||
("MaxConnectionTime", | |||
"Terminate when a client has been connected for s seconds", | |||
0); | |||
0, 0); | |||
rfb::IntParameter rfb::Server::maxIdleTime | |||
("MaxIdleTime", | |||
"Terminate after s seconds of user inactivity", | |||
0); | |||
0, 0); | |||
rfb::IntParameter rfb::Server::clientWaitTimeMillis | |||
("ClientWaitTimeMillis", | |||
"The number of milliseconds to wait for a client which is no longer " | |||
"responding", | |||
20000); | |||
rfb::StringParameter rfb::Server::sec_types | |||
("SecurityTypes", | |||
"Specify which security scheme to use for incoming connections (None, VncAuth)", | |||
"VncAuth"); | |||
rfb::StringParameter rfb::Server::rev_sec_types | |||
("ReverseSecurityTypes", | |||
"Specify encryption scheme to use for reverse connections (None)", | |||
"None"); | |||
20000, 0); | |||
rfb::BoolParameter rfb::Server::compareFB | |||
("CompareFB", | |||
"Perform pixel comparison on framebuffer to reduce unnecessary updates", | |||
@@ -101,8 +92,3 @@ rfb::BoolParameter rfb::Server::queryConnect | |||
("QueryConnect", | |||
"Prompt the local user to accept or reject incoming connections.", | |||
false); | |||
rfb::IntParameter rfb::Server::blacklistLevel | |||
("BlacklistLevel", | |||
"When to test whether particular host should be blacklisted. (0 = Never, " | |||
"1 = Test before authentication, 2 = Test on connect)", | |||
1); |
@@ -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 | |||
@@ -37,8 +37,6 @@ namespace rfb { | |||
static IntParameter maxConnectionTime; | |||
static IntParameter maxIdleTime; | |||
static IntParameter clientWaitTimeMillis; | |||
static StringParameter sec_types; | |||
static StringParameter rev_sec_types; | |||
static BoolParameter compareFB; | |||
static BoolParameter protocol3_3; | |||
static BoolParameter alwaysShared; | |||
@@ -49,7 +47,6 @@ namespace rfb { | |||
static BoolParameter acceptCutText; | |||
static BoolParameter sendCutText; | |||
static BoolParameter queryConnect; | |||
static IntParameter blacklistLevel; | |||
}; | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -25,7 +25,7 @@ | |||
#define __RFB_THREADING_H__ | |||
#ifdef WIN32 | |||
#include <rfb/win32/Threading_win32.h> | |||
#include <rfb_win32/Threading.h> | |||
#endif | |||
#endif // __RFB_THREADING_H__ |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 |
@@ -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 | |||
@@ -30,34 +30,34 @@ using namespace rfb; | |||
static LogWriter vlog("UpdateTracker"); | |||
// -=- ClippedUpdateTracker | |||
void ClippedUpdateTracker::add_changed(const Region ®ion) { | |||
child.add_changed(region.intersect(cliprgn)); | |||
// -=- ClippingUpdateTracker | |||
void ClippingUpdateTracker::add_changed(const Region ®ion) { | |||
ut->add_changed(region.intersect(clipRect)); | |||
} | |||
void ClippedUpdateTracker::add_copied(const Region &dest, const Point &delta) { | |||
void ClippingUpdateTracker::add_copied(const Region &dest, const Point &delta) { | |||
// Clip the destination to the display area | |||
Region clipdest = dest.intersect(cliprgn); | |||
Region clipdest = dest.intersect(clipRect); | |||
if (clipdest.is_empty()) return; | |||
// Clip the source to the screen | |||
Region tmp = clipdest; | |||
tmp.translate(delta.negate()); | |||
tmp.assign_intersect(cliprgn); | |||
tmp.assign_intersect(clipRect); | |||
if (!tmp.is_empty()) { | |||
// Translate the source back to a destination region | |||
tmp.translate(delta); | |||
// Pass the copy region to the child tracker | |||
child.add_copied(tmp, delta); | |||
ut->add_copied(tmp, delta); | |||
} | |||
// And add any bits that we had to remove to the changed region | |||
tmp = clipdest.subtract(tmp); | |||
if (!tmp.is_empty()) { | |||
child.add_changed(tmp); | |||
} | |||
if (!tmp.is_empty()) | |||
ut->add_changed(tmp); | |||
} | |||
// SimpleUpdateTracker | |||
@@ -140,7 +140,7 @@ void SimpleUpdateTracker::subtract(const Region& region) { | |||
changed.assign_subtract(region); | |||
} | |||
void SimpleUpdateTracker::get_update(UpdateInfo* info, const Region& clip) | |||
void SimpleUpdateTracker::getUpdateInfo(UpdateInfo* info, const Region& clip) | |||
{ | |||
copied.assign_subtract(changed); | |||
info->changed = changed.intersect(clip); | |||
@@ -148,25 +148,9 @@ void SimpleUpdateTracker::get_update(UpdateInfo* info, const Region& clip) | |||
info->copy_delta = copy_delta; | |||
} | |||
void SimpleUpdateTracker::flush_update(UpdateTracker &info, | |||
const Region &cliprgn) | |||
{ | |||
Region copied_clipped = copied.intersect(cliprgn); | |||
Region changed_clipped = changed.intersect(cliprgn); | |||
copied.assign_subtract(copied_clipped); | |||
changed.assign_subtract(changed_clipped); | |||
if (!copied_clipped.is_empty()) { | |||
info.add_copied(copied_clipped, copy_delta); | |||
} | |||
if (!changed_clipped.is_empty()) | |||
info.add_changed(changed_clipped); | |||
} | |||
void SimpleUpdateTracker::get_update(UpdateTracker &to) const { | |||
if (!copied.is_empty()) { | |||
to.add_copied(copied, copy_delta); | |||
} | |||
if (!changed.is_empty()) { | |||
to.add_changed(changed); | |||
} | |||
void SimpleUpdateTracker::copyTo(UpdateTracker* to) const { | |||
if (!copied.is_empty()) | |||
to->add_copied(copied, copy_delta); | |||
if (!changed.is_empty()) | |||
to->add_changed(changed); | |||
} |
@@ -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 | |||
@@ -47,25 +47,24 @@ namespace rfb { | |||
virtual void add_copied(const Region &dest, const Point &delta) = 0; | |||
}; | |||
class ClippedUpdateTracker : public UpdateTracker { | |||
class ClippingUpdateTracker : public UpdateTracker { | |||
public: | |||
ClippedUpdateTracker(UpdateTracker &child_) : child(child_) {}; | |||
ClippedUpdateTracker(UpdateTracker &child_, | |||
const Region &cliprgn_) : child(child_), cliprgn(cliprgn_) {}; | |||
virtual ~ClippedUpdateTracker() {}; | |||
virtual void set_clip_region(const Region cliprgn_) {cliprgn = cliprgn_;}; | |||
ClippingUpdateTracker() : ut(0) {} | |||
ClippingUpdateTracker(UpdateTracker* ut_, const Rect& r=Rect()) : ut(ut_), clipRect(r) {} | |||
void setUpdateTracker(UpdateTracker* ut_) {ut = ut_;} | |||
void setClipRect(const Rect& cr) {clipRect = cr;} | |||
virtual void add_changed(const Region ®ion); | |||
virtual void add_copied(const Region &dest, const Point &delta); | |||
protected: | |||
UpdateTracker &child; | |||
Region cliprgn; | |||
UpdateTracker* ut; | |||
Region clipRect; | |||
}; | |||
class SimpleUpdateTracker : public UpdateTracker { | |||
public: | |||
SimpleUpdateTracker(bool use_copyrect=false); | |||
SimpleUpdateTracker(bool use_copyrect=true); | |||
virtual ~SimpleUpdateTracker(); | |||
virtual void enable_copyrect(bool enable); | |||
@@ -75,13 +74,10 @@ namespace rfb { | |||
virtual void subtract(const Region& region); | |||
// Fill the supplied UpdateInfo structure with update information | |||
virtual void get_update(UpdateInfo* info, const Region& cliprgn); | |||
// Pass the current updates to the supplied tracker | |||
virtual void get_update(UpdateTracker &to) const; | |||
virtual void getUpdateInfo(UpdateInfo* info, const Region& cliprgn); | |||
// Also removes the updates that are returned from this update tracker | |||
virtual void flush_update(UpdateTracker &to, const Region &cliprgn); | |||
// Copy the contained updates to another tracker | |||
virtual void copyTo(UpdateTracker* to) const; | |||
// Get the changed/copied regions |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 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 | |||
@@ -20,12 +20,11 @@ | |||
namespace rfb { | |||
class UserPasswdGetter { | |||
public: | |||
// getUserPasswd gets the username and password. This might | |||
// involve a dialog, getpass(), etc. The user buffer pointer | |||
// can be null, in which case no user name will be retrieved. | |||
// The caller MUST delete [] the result(s) iff the | |||
// call succeeds (returns true), and ignore them if failed. | |||
virtual bool getUserPasswd(char** user, char** password)=0; | |||
// getUserPasswd gets the username and password. This might involve a | |||
// dialog, getpass(), etc. The user buffer pointer can be null, in which | |||
// case no user name will be retrieved. The caller MUST delete [] the | |||
// result(s). | |||
virtual void getUserPasswd(char** user, char** password)=0; | |||
}; | |||
} | |||
#endif |
@@ -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,6 +21,7 @@ | |||
#include <rfb/secTypes.h> | |||
#include <rfb/ServerCore.h> | |||
#include <rfb/ComparingUpdateTracker.h> | |||
#include <rfb/KeyRemapper.h> | |||
#define XK_MISCELLANY | |||
#define XK_XKB_KEYS | |||
#include <rfb/keysymdef.h> | |||
@@ -31,8 +32,8 @@ static LogWriter vlog("VNCSConnST"); | |||
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, | |||
bool reverse) | |||
: sock(s), reverseConnection(reverse), server(server_), | |||
image_getter(server->useEconomicTranslate), | |||
: SConnection(server_->securityFactory, reverse), sock(s), server(server_), | |||
updates(false), image_getter(server->useEconomicTranslate), | |||
drawRenderedCursor(false), removeRenderedCursor(false), | |||
pointerEventTime(0), accessRights(AccessDefault), | |||
startTime(time(0)) | |||
@@ -41,21 +42,11 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, | |||
peerEndpoint.buf = sock->getPeerEndpoint(); | |||
VNCServerST::connectionsLog.write(1,"accepted: %s", peerEndpoint.buf); | |||
// Configure the socket | |||
setSocketTimeouts(); | |||
lastEventTime = time(0); | |||
// Initialise security | |||
CharArray sec_types_str; | |||
if (reverseConnection) | |||
sec_types_str.buf = rfb::Server::rev_sec_types.getData(); | |||
else | |||
sec_types_str.buf = rfb::Server::sec_types.getData(); | |||
std::list<int> sec_types = parseSecTypes(sec_types_str.buf); | |||
std::list<int>::iterator i; | |||
for (i=sec_types.begin(); i!=sec_types.end(); i++) { | |||
addSecType(*i); | |||
} | |||
// Add this client to the VNCServerST | |||
server->clients.push_front(this); | |||
} | |||
@@ -64,7 +55,8 @@ VNCSConnectionST::~VNCSConnectionST() | |||
{ | |||
// If we reach here then VNCServerST is deleting us! | |||
VNCServerST::connectionsLog.write(1,"closed: %s (%s)", | |||
peerEndpoint.buf, closeReason.buf); | |||
peerEndpoint.buf, | |||
(closeReason.buf) ? closeReason.buf : ""); | |||
// Release any keys the client still had pressed | |||
std::set<rdr::U32>::iterator i; | |||
@@ -103,16 +95,17 @@ void VNCSConnectionST::close(const char* reason) | |||
server->lastDisconnectTime = time(0); | |||
} | |||
// Just shutdown the socket. This will cause processMessages to | |||
// eventually fail, causing us and our socket to be deleted. | |||
// Just shutdown the socket and mark our state as closing. Eventually the | |||
// calling code will call VNCServerST's removeSocket() method causing us to | |||
// be deleted. | |||
sock->shutdown(); | |||
setState(RFBSTATE_CLOSING); | |||
} | |||
bool VNCSConnectionST::processMessages() | |||
void VNCSConnectionST::processMessages() | |||
{ | |||
if (state() == RFBSTATE_CLOSING) return false; | |||
if (state() == RFBSTATE_CLOSING) return; | |||
try { | |||
// - Now set appropriate socket timeouts and process data | |||
setSocketTimeouts(); | |||
@@ -124,15 +117,11 @@ bool VNCSConnectionST::processMessages() | |||
if (!clientsReadyBefore && !requested.is_empty()) | |||
server->desktop->framebufferUpdateRequest(); | |||
return true; | |||
} catch (rdr::EndOfStream&) { | |||
close("Clean disconnection"); | |||
} catch (rdr::Exception &e) { | |||
close(e.str()); | |||
} | |||
return false; | |||
} | |||
void VNCSConnectionST::writeFramebufferUpdateOrClose() | |||
@@ -170,9 +159,11 @@ void VNCSConnectionST::pixelBufferChange() | |||
cp.width = server->pb->width(); | |||
cp.height = server->pb->height(); | |||
if (!writer()->writeSetDesktopSize()) { | |||
close("Client does not support desktop resize"); | |||
return; | |||
if (state() == RFBSTATE_NORMAL) { | |||
if (!writer()->writeSetDesktopSize()) { | |||
close("Client does not support desktop resize"); | |||
return; | |||
} | |||
} | |||
} | |||
// Just update the whole screen at the moment because we're too lazy to | |||
@@ -248,13 +239,13 @@ int VNCSConnectionST::checkIdleTimeout() | |||
// now. | |||
vlog.info("Time has gone forwards - resetting idle timeout"); | |||
lastEventTime = now; | |||
return idleTimeout; | |||
return secsToMillis(idleTimeout); | |||
} | |||
if (timeLeft <= 0) { | |||
close("Idle timeout"); | |||
return 0; | |||
} | |||
return timeLeft * 1000; | |||
return secsToMillis(timeLeft); | |||
} | |||
// renderedCursorChange() is called whenever the server-side rendered cursor | |||
@@ -302,29 +293,10 @@ void VNCSConnectionST::approveConnectionOrClose(bool accept, | |||
// -=- Callbacks from SConnection | |||
void VNCSConnectionST::versionReceived() { | |||
CharArray address(sock->getPeerAddress()); | |||
if ((rfb::Server::blacklistLevel == 1) && | |||
server->blHosts->isBlackmarked(address.buf)) { | |||
server->connectionsLog.error("blacklisted: %s", address.buf); | |||
throwConnFailedException("Too many security failures"); | |||
} | |||
} | |||
SSecurity* VNCSConnectionST::getSSecurity(int secType) { | |||
if (!server->securityFactory) | |||
throw rdr::Exception("no SSecurityFactory registered!"); | |||
return server->securityFactory->getSSecurity(secType, reverseConnection); | |||
} | |||
void VNCSConnectionST::authSuccess() | |||
{ | |||
lastEventTime = time(0); | |||
// - Authentication succeeded - clear from blacklist | |||
CharArray name; name.buf = sock->getPeerAddress(); | |||
server->blHosts->clearBlackmark(name.buf); | |||
server->startDesktop(); | |||
// - Set the connection parameters appropriately | |||
@@ -346,18 +318,36 @@ void VNCSConnectionST::authSuccess() | |||
void VNCSConnectionST::queryConnection(const char* userName) | |||
{ | |||
// - Authentication succeeded - clear from blacklist | |||
CharArray name; name.buf = sock->getPeerAddress(); | |||
server->blHosts->clearBlackmark(name.buf); | |||
// - Special case to provide a more useful error message | |||
if (rfb::Server::neverShared && !rfb::Server::disconnectClients && | |||
server->authClientCount() > 0) { | |||
approveConnection(false, "The server is already in use"); | |||
return; | |||
} | |||
// - Does the client have the right to bypass the query? | |||
if (reverseConnection || !rfb::Server::queryConnect || | |||
if (reverseConnection || | |||
!(rfb::Server::queryConnect || sock->requiresQuery()) || | |||
(accessRights & AccessNoQuery)) | |||
{ | |||
approveConnection(true); | |||
return; | |||
} | |||
// - Get the server to display an Accept/Reject dialog, if required | |||
// If a dialog is displayed, the result will be PENDING, and the | |||
// server will call approveConnection at a later time | |||
CharArray reason; | |||
VNCServerST::queryResult qr = server->queryConnection(sock, userName, | |||
&reason.buf); | |||
if (qr == VNCServerST::PENDING) return; | |||
if (qr == VNCServerST::PENDING) | |||
return; | |||
// - If server returns ACCEPT/REJECT then pass result to SConnection | |||
approveConnection(qr == VNCServerST::ACCEPT, reason.buf); | |||
} | |||
@@ -372,7 +362,8 @@ void VNCSConnectionST::clientInit(bool shared) | |||
vlog.debug("non-shared connection - closing clients"); | |||
server->closeClients("Non-shared connection requested", getSock()); | |||
} else { | |||
// - Refuse this connection if there are existing clients, in addition to this one | |||
// - Refuse this connection if there are existing clients, in addition to | |||
// this one | |||
if (server->authClientCount() > 1) { | |||
close("Server is already in use"); | |||
return; | |||
@@ -392,14 +383,14 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf) | |||
setCursor(); | |||
} | |||
void VNCSConnectionST::pointerEvent(int x, int y, int buttonMask) | |||
void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask) | |||
{ | |||
pointerEventTime = lastEventTime = time(0); | |||
server->lastUserInputTime = lastEventTime; | |||
if (!(accessRights & AccessPtrEvents)) return; | |||
if (!rfb::Server::acceptPointerEvents) return; | |||
if (!server->pointerClient || server->pointerClient == this) { | |||
pointerEventPos = Point(x, y); | |||
pointerEventPos = pos; | |||
if (buttonMask) | |||
server->pointerClient = this; | |||
else | |||
@@ -432,6 +423,10 @@ void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) { | |||
if (!(accessRights & AccessKeyEvents)) return; | |||
if (!rfb::Server::acceptKeyEvents) return; | |||
// Remap the key if required | |||
if (server->keyRemapper) | |||
key = server->keyRemapper->remapKey(key); | |||
// Turn ISO_Left_Tab into shifted Tab. | |||
VNCSConnectionSTShiftPresser shiftPresser(server->desktop); | |||
if (key == XK_ISO_Left_Tab) { | |||
@@ -522,10 +517,9 @@ void VNCSConnectionST::writeSetCursorCallback() | |||
image_getter.translatePixels(server->cursor.data, transData, | |||
server->cursor.area()); | |||
writer()->writeSetCursor(server->cursor.width(), | |||
server->cursor.height(), | |||
server->cursor.hotspot.x, | |||
server->cursor.hotspot.y, | |||
transData, server->cursor.mask.buf); | |||
server->cursor.height(), | |||
server->cursor.hotspot, | |||
transData, server->cursor.mask.buf); | |||
} | |||
@@ -574,7 +568,7 @@ void VNCSConnectionST::writeFramebufferUpdate() | |||
if (renderedCursorRect.is_empty()) { | |||
drawRenderedCursor = false; | |||
} else if (!updates.get_changed().union_(updates.get_copied()) | |||
.intersect(renderedCursorRect).is_empty()) { | |||
.intersect(renderedCursorRect).is_empty()) { | |||
drawRenderedCursor = true; | |||
} | |||
@@ -589,7 +583,7 @@ void VNCSConnectionST::writeFramebufferUpdate() | |||
UpdateInfo update; | |||
updates.enable_copyrect(cp.useCopyRect); | |||
updates.get_update(&update, requested); | |||
updates.getUpdateInfo(&update, requested); | |||
if (!update.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) { | |||
// Compute the number of rectangles. Tight encoder makes the things more | |||
// complicated as compared to the original RealVNC. | |||
@@ -660,11 +654,9 @@ void VNCSConnectionST::setCursor() | |||
void VNCSConnectionST::setSocketTimeouts() | |||
{ | |||
int timeoutms = rfb::Server::clientWaitTimeMillis; | |||
if (timeoutms == 0 || timeoutms > rfb::Server::idleTimeout * 1000) { | |||
timeoutms = rfb::Server::idleTimeout * 1000; | |||
if (timeoutms == 0) | |||
timeoutms = -1; | |||
} | |||
soonestTimeout(&timeoutms, secsToMillis(rfb::Server::idleTimeout)); | |||
if (timeoutms == 0) | |||
timeoutms = -1; | |||
sock->inStream().setTimeout(timeoutms); | |||
sock->outStream().setTimeout(timeoutms); | |||
} |