Commit 93be927b authored by dscho's avatar dscho

Introduce generic protocol extension method. Deprecate

the processCustomClientMessage() method.
parent 94fcd86c
2005-09-27 Rohit Kumar <rokumar@novell.com>
* libvncserver/{cargs,sockets,main,rfbserver}.c,
rfb/rfb.h: Provide a generic means to extend the RFB
protocol: rfbRegisterProtocolExtension(extension). This
deprecates the current (very limited) option to override
rfbScreenInfoPtr->processCustomClientMessage(client).
2005-09-26 Rohit Kumar <rokumar@novell.com>
* libvncserver/{auth,main,rfbserver}.c, rfb/{rfb,rfbproto}.h:
support VNC protocol version 3.7. This allows to add security
......
......@@ -19,6 +19,8 @@ extern int rfbStringToAddr(char *str, in_addr_t *iface);
void
rfbUsage(void)
{
rfbProtocolExtension* extension;
fprintf(stderr, "-rfbport port TCP port for RFB protocol\n");
fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n");
fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n"
......@@ -40,6 +42,11 @@ rfbUsage(void)
fprintf(stderr, "-progressive height enable progressive updating for slow links\n");
fprintf(stderr, "-listen ipaddr listen for connections only on network interface with\n");
fprintf(stderr, " addr ipaddr. '-listen localhost' and hostname work too.\n");
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->usage)
extension->usage();
rfbReleaseExtensionIterator();
}
/* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
......@@ -138,10 +145,22 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
return FALSE;
}
} else {
rfbProtocolExtension* extension;
int handled=0;
for(extension=rfbGetExtensionIterator();handled==0 && extension;
extension=extension->next)
if(extension->processArgument)
handled = extension->processArgument(argv + i);
rfbReleaseExtensionIterator();
if(handled==0) {
i++;
i1=i;
continue;
}
i+=handled-1;
}
/* we just remove the processed arguments from the list */
rfbPurgeArguments(argc,&i1,i-i1+1,argv);
i=i1;
......
......@@ -40,6 +40,7 @@
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
static MUTEX(logMutex);
static MUTEX(extMutex);
#endif
static int rfbEnableLogging=1;
......@@ -50,6 +51,43 @@ char rfbEndianTest = 0;
char rfbEndianTest = -1;
#endif
/*
* Protocol extensions
*/
static rfbProtocolExtension* rfbExtensionHead = NULL;
void
rfbRegisterProtocolExtension(rfbProtocolExtension* extension)
{
rfbProtocolExtension* last;
LOCK(extMutex);
last = extension;
while(last->next)
last = last->next;
last->next = rfbExtensionHead;
rfbExtensionHead = extension;
UNLOCK(extMutex);
}
rfbProtocolExtension* rfbGetExtensionIterator()
{
LOCK(extMutex);
return rfbExtensionHead;
}
void rfbReleaseExtensionIterator()
{
UNLOCK(extMutex);
}
/*
* Logging
*/
void rfbLogEnable(int enabled) {
rfbEnableLogging=enabled;
}
......
......@@ -3,6 +3,7 @@
*/
/*
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
......@@ -347,6 +348,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->progressiveSliceY = 0;
cl->extensions = NULL;
sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
rfbProtocolMinorVersion);
......@@ -603,6 +606,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
int len, n;
rfbClientIteratorPtr iterator;
rfbClientPtr otherCl;
rfbProtocolExtension* extension;
if ((n = rfbReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
if (n == 0)
......@@ -613,7 +617,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return;
}
memset(buf,0,256);
memset(buf,0,sizeof(buf));
si->framebufferWidth = Swap16IfLE(cl->screen->width);
si->framebufferHeight = Swap16IfLE(cl->screen->height);
......@@ -632,6 +636,19 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return;
}
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->init) {
void* data;
if(extension->init(cl, &data)) {
rfbExtensionData* extensionData=calloc(sizeof(rfbExtensionData),1);
extensionData->extension=extension;
extensionData->data=data;
extensionData->next=cl->extensions;
cl->extensions=extensionData;
}
}
rfbReleaseExtensionIterator();
cl->state = RFB_NORMAL;
if (!cl->reverseConnection &&
......@@ -1046,16 +1063,28 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
default:
{
rfbExtensionData* extension;
if(cl->screen->processCustomClientMessage(cl,msg.type))
for(extension=cl->extensions; extension; extension=extension->next)
if(extension->extension->handleMessage &&
extension->extension->handleMessage(cl, extension->data, msg))
return;
if(cl->screen->processCustomClientMessage(cl,msg.type)) {
rfbLog("Warning: this program uses processCustomClientMessage, "
"which is deprecated.\n"
"Please use rfbRegisterProtocolExtension instead.\n");
return;
}
rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
msg.type);
rfbLog(" ... closing connection\n");
rfbCloseClient(cl);
return;
}
}
}
......
......@@ -19,6 +19,7 @@
*/
/*
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
......@@ -344,6 +345,12 @@ rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
void
rfbCloseClient(rfbClientPtr cl)
{
rfbExtensionData* extension;
for(extension=cl->extensions; extension; extension=extension->next)
if(extension->extension->close)
extension->extension->close(cl, extension->data);
LOCK(cl->updateMutex);
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
if (cl->sock != -1)
......
......@@ -145,7 +145,7 @@ typedef struct {
} rfbColourMap;
/*
* Security handling (RFB protocol version 3.7
* Security handling (RFB protocol version 3.7)
*/
typedef struct _rfbSecurity {
......@@ -154,6 +154,29 @@ typedef struct _rfbSecurity {
struct _rfbSecurity* next;
} rfbSecurityHandler;
/*
* Protocol extension handling.
*/
typedef struct _rfbProtocolExtension {
/* returns TRUE if extension should be activated */
rfbBool (*init)(struct _rfbClientRec* client, void** data);
/* returns TRUE if message was handled */
rfbBool (*handleMessage)(struct _rfbClientRec* client,
void* data,
rfbClientToServerMsg message);
void (*close)(struct _rfbClientRec* client, void* data);
void (*usage)(void);
/* processArguments returns the number of handled arguments */
int (*processArgument)(char *argv[]);
struct _rfbProtocolExtension* next;
} rfbProtocolExtension;
typedef struct _rfbExtensionData {
rfbProtocolExtension* extension;
void* data;
struct _rfbExtensionData* next;
} rfbExtensionData;
/*
* Per-screen (framebuffer) structure. There can be as many as you wish,
......@@ -481,6 +504,8 @@ typedef struct _rfbClientRec {
/* if progressive updating is on, this variable holds the current
* y coordinate of the progressive slice. */
int progressiveSliceY;
rfbExtensionData* extensions;
} rfbClientRec, *rfbClientPtr;
/*
......@@ -760,6 +785,10 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
void rfbDoNothingWithClient(rfbClientPtr cl);
enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
struct _rfbProtocolExtension* rfbGetExtensionIterator();
void rfbReleaseExtensionIterator();
rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
/* to check against plain passwords */
rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment