summaryrefslogtreecommitdiffstats
path: root/libvncserver/httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver/httpd.c')
-rw-r--r--libvncserver/httpd.c91
1 files changed, 76 insertions, 15 deletions
diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c
index 3025aae..ed91e46 100644
--- a/libvncserver/httpd.c
+++ b/libvncserver/httpd.c
@@ -3,6 +3,7 @@
*/
/*
+ * Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
* Copyright (C) 2002 RealVNC Ltd.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
@@ -102,17 +103,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 +132,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 +157,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 +172,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 +197,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 +259,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 +386,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 +621,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 +631,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 {