|
|
|
@ -102,17 +102,27 @@ rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
rfbScreen->httpPort = rfbScreen->port-100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rfbLog("Listening for HTTP connections on TCP port %d\n", rfbScreen->httpPort);
|
|
|
|
|
|
|
|
|
|
rfbLog(" URL http://%s:%d\n",rfbScreen->thisHost,rfbScreen->httpPort);
|
|
|
|
|
|
|
|
|
|
if ((rfbScreen->httpListenSock =
|
|
|
|
|
rfbListenOnTCPPort(rfbScreen->httpPort, rfbScreen->listenInterface)) < 0) {
|
|
|
|
|
rfbLogPerror("ListenOnTCPPort");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rfbLog("Listening for HTTP connections on TCP port %d\n", rfbScreen->httpPort);
|
|
|
|
|
rfbLog(" URL http://%s:%d\n",rfbScreen->thisHost,rfbScreen->httpPort);
|
|
|
|
|
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
if (rfbScreen->http6Port == 0) {
|
|
|
|
|
rfbScreen->http6Port = rfbScreen->ipv6port-100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*AddEnabledDevice(httpListenSock);*/
|
|
|
|
|
if ((rfbScreen->httpListen6Sock
|
|
|
|
|
= rfbListenOnTCP6Port(rfbScreen->http6Port, rfbScreen->listen6Interface)) < 0) {
|
|
|
|
|
/* ListenOnTCP6Port has its own detailed error printout */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rfbLog("Listening for HTTP connections on TCP6 port %d\n", rfbScreen->http6Port);
|
|
|
|
|
rfbLog(" URL http://%s:%d\n",rfbScreen->thisHost,rfbScreen->http6Port);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen) {
|
|
|
|
@ -121,6 +131,18 @@ void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen) {
|
|
|
|
|
FD_CLR(rfbScreen->httpSock,&rfbScreen->allFds);
|
|
|
|
|
rfbScreen->httpSock=-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(rfbScreen->httpListenSock>-1) {
|
|
|
|
|
close(rfbScreen->httpListenSock);
|
|
|
|
|
FD_CLR(rfbScreen->httpListenSock,&rfbScreen->allFds);
|
|
|
|
|
rfbScreen->httpListenSock=-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(rfbScreen->httpListen6Sock>-1) {
|
|
|
|
|
close(rfbScreen->httpListen6Sock);
|
|
|
|
|
FD_CLR(rfbScreen->httpListen6Sock,&rfbScreen->allFds);
|
|
|
|
|
rfbScreen->httpListen6Sock=-1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -134,7 +156,11 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
int nfds;
|
|
|
|
|
fd_set fds;
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
struct sockaddr_storage addr;
|
|
|
|
|
#else
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
#endif
|
|
|
|
|
socklen_t addrlen = sizeof(addr);
|
|
|
|
|
|
|
|
|
|
if (!rfbScreen->httpDir)
|
|
|
|
@ -145,12 +171,15 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
|
|
|
|
|
FD_ZERO(&fds);
|
|
|
|
|
FD_SET(rfbScreen->httpListenSock, &fds);
|
|
|
|
|
if (rfbScreen->httpListen6Sock >= 0) {
|
|
|
|
|
FD_SET(rfbScreen->httpListen6Sock, &fds);
|
|
|
|
|
}
|
|
|
|
|
if (rfbScreen->httpSock >= 0) {
|
|
|
|
|
FD_SET(rfbScreen->httpSock, &fds);
|
|
|
|
|
}
|
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
|
|
|
|
|
nfds = select(max(rfbScreen->httpListen6Sock, max(rfbScreen->httpSock,rfbScreen->httpListenSock)) + 1, &fds, NULL, NULL, &tv);
|
|
|
|
|
if (nfds == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -167,19 +196,36 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
httpProcessInput(rfbScreen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
|
|
|
|
|
if (FD_ISSET(rfbScreen->httpListenSock, &fds) || FD_ISSET(rfbScreen->httpListen6Sock, &fds)) {
|
|
|
|
|
if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);
|
|
|
|
|
|
|
|
|
|
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
|
|
|
|
|
(struct sockaddr *)&addr, &addrlen)) < 0) {
|
|
|
|
|
rfbLogPerror("httpCheckFds: accept");
|
|
|
|
|
return;
|
|
|
|
|
if(FD_ISSET(rfbScreen->httpListenSock, &fds)) {
|
|
|
|
|
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock, (struct sockaddr *)&addr, &addrlen)) < 0) {
|
|
|
|
|
rfbLogPerror("httpCheckFds: accept");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(FD_ISSET(rfbScreen->httpListen6Sock, &fds)) {
|
|
|
|
|
if ((rfbScreen->httpSock = accept(rfbScreen->httpListen6Sock, (struct sockaddr *)&addr, &addrlen)) < 0) {
|
|
|
|
|
rfbLogPerror("httpCheckFds: accept");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef USE_LIBWRAP
|
|
|
|
|
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
|
|
|
|
|
char host[1024];
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
|
|
|
|
|
rfbLogPerror("httpCheckFds: error in getnameinfo");
|
|
|
|
|
host[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
memcpy(host, inet_ntoa(addr.sin_addr), sizeof(host));
|
|
|
|
|
#endif
|
|
|
|
|
if(!hosts_ctl("vnc",STRING_UNKNOWN, host,
|
|
|
|
|
STRING_UNKNOWN)) {
|
|
|
|
|
rfbLog("Rejected HTTP connection from client %s\n",
|
|
|
|
|
inet_ntoa(addr.sin_addr));
|
|
|
|
|
host);
|
|
|
|
|
close(rfbScreen->httpSock);
|
|
|
|
|
rfbScreen->httpSock=-1;
|
|
|
|
|
return;
|
|
|
|
@ -212,7 +258,11 @@ static rfbClientRec cl;
|
|
|
|
|
static void
|
|
|
|
|
httpProcessInput(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
struct sockaddr_storage addr;
|
|
|
|
|
#else
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
#endif
|
|
|
|
|
socklen_t addrlen = sizeof(addr);
|
|
|
|
|
char fullFname[512];
|
|
|
|
|
char params[1024];
|
|
|
|
@ -335,8 +385,16 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen);
|
|
|
|
|
#ifdef LIBVNCSERVER_IPv6
|
|
|
|
|
char host[1024];
|
|
|
|
|
if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
|
|
|
|
|
rfbLogPerror("httpProcessInput: error in getnameinfo");
|
|
|
|
|
}
|
|
|
|
|
rfbLog("httpd: get '%s' for %s\n", fname+1, host);
|
|
|
|
|
#else
|
|
|
|
|
rfbLog("httpd: get '%s' for %s\n", fname+1,
|
|
|
|
|
inet_ntoa(addr.sin_addr));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Extract parameters from the URL string if necessary */
|
|
|
|
|
|
|
|
|
@ -562,7 +620,8 @@ parseParams(const char *request, char *result, int max_bytes)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check if the string consists only of alphanumeric characters, '+'
|
|
|
|
|
* signs, underscores, and dots. Replace all '+' signs with spaces.
|
|
|
|
|
* signs, underscores, dots, colons and square brackets.
|
|
|
|
|
* Replace all '+' signs with spaces.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static rfbBool
|
|
|
|
@ -571,7 +630,8 @@ validateString(char *str)
|
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
|
|
for (ptr = str; *ptr != '\0'; ptr++) {
|
|
|
|
|
if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.') {
|
|
|
|
|
if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.'
|
|
|
|
|
&& *ptr != ':' && *ptr != '[' && *ptr != ']' ) {
|
|
|
|
|
if (*ptr == '+') {
|
|
|
|
|
*ptr = ' ';
|
|
|
|
|
} else {
|
|
|
|
|