diff options
Diffstat (limited to 'libvncserver/httpd.c')
-rw-r--r-- | libvncserver/httpd.c | 91 |
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 { |