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