Commit 727b0257 authored by dscho's avatar dscho

synchronized with tightVNC 1.2.5

parent 598c460c
No preview for this file type
<!-- index.vnc - default html page for Java VNC viewer applet. On any file <!-- index.vnc - default html page for Java VNC viewer applet. On any file
ending in .vnc, the HTTP server embedded in Xvnc will substitute the ending in .vnc, the HTTP server embedded in Xvnc will substitute the
following variables when preceded by a dollar: USER, DESKTOP, DISPLAY, following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT. Use two dollar signs APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT, PARAMS. Use two dollar
($$) to get a dollar sign in the generated html. --> signs ($$) to get a dollar sign in the generated html. -->
<HTML> <HTML>
<TITLE> <TITLE>
......
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
static void httpProcessInput(); static void httpProcessInput();
static Bool compareAndSkip(char **ptr, const char *str); static Bool compareAndSkip(char **ptr, const char *str);
static Bool parseParams(const char *request, char *result, int max_bytes);
static Bool validateString(char *str);
/* /*
int httpPort = 0; int httpPort = 0;
...@@ -153,7 +155,7 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen) ...@@ -153,7 +155,7 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
#ifdef USE_LIBWRAP #ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) { STRING_UNKNOWN)) {
rfbLog("Rejected connection from client %s\n", rfbLog("Rejected HTTP connection from client %s\n",
inet_ntoa(addr.sin_addr)); inet_ntoa(addr.sin_addr));
#else #else
if ((rfbScreen->httpFP = fdopen(rfbScreen->httpSock, "r+")) == NULL) { if ((rfbScreen->httpFP = fdopen(rfbScreen->httpSock, "r+")) == NULL) {
...@@ -197,7 +199,9 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -197,7 +199,9 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
char fullFname[256]; char fullFname[512];
char params[1024];
char *ptr;
char *fname; char *fname;
unsigned int maxFnameLen; unsigned int maxFnameLen;
FILE* fd; FILE* fd;
...@@ -209,14 +213,14 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -209,14 +213,14 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
cl.sock=rfbScreen->httpSock; cl.sock=rfbScreen->httpSock;
if (strlen(rfbScreen->httpDir) > 200) { if (strlen(rfbScreen->httpDir) > 255) {
rfbLog("-httpd directory too long\n"); rfbLog("-httpd directory too long\n");
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} }
strcpy(fullFname, rfbScreen->httpDir); strcpy(fullFname, rfbScreen->httpDir);
fname = &fullFname[strlen(fullFname)]; fname = &fullFname[strlen(fullFname)];
maxFnameLen = 255 - strlen(fullFname); maxFnameLen = 511 - strlen(fullFname);
buf_filled=0; buf_filled=0;
...@@ -250,7 +254,7 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -250,7 +254,7 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
/* Process the request. */ /* Process the request. */
if (strncmp(buf, "GET ", 4)) { if (strncmp(buf, "GET ", 4)) {
rfbLog("no GET line\n"); rfbLog("httpd: no GET line\n");
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} else { } else {
...@@ -259,26 +263,26 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -259,26 +263,26 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
} }
if (strlen(buf) > maxFnameLen) { if (strlen(buf) > maxFnameLen) {
rfbLog("GET line too long\n"); rfbLog("httpd: GET line too long\n");
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} }
if (sscanf(buf, "GET %s HTTP/1.0", fname) != 1) { if (sscanf(buf, "GET %s HTTP/1.0", fname) != 1) {
rfbLog("couldn't parse GET line\n"); rfbLog("httpd: couldn't parse GET line\n");
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} }
if (fname[0] != '/') { if (fname[0] != '/') {
rfbLog("filename didn't begin with '/'\n"); rfbLog("httpd: filename didn't begin with '/'\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR)); WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} }
if (strchr(fname+1, '/') != NULL) { if (strchr(fname+1, '/') != NULL) {
rfbLog("asking for file in other directory\n"); rfbLog("httpd: asking for file in other directory\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR)); WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
...@@ -288,6 +292,19 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -288,6 +292,19 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
rfbLog("httpd: get '%s' for %s\n", fname+1, rfbLog("httpd: get '%s' for %s\n", fname+1,
inet_ntoa(addr.sin_addr)); inet_ntoa(addr.sin_addr));
/* Extract parameters from the URL string if necessary */
params[0] = '\0';
ptr = strchr(fname, '?');
if (ptr != NULL) {
*ptr = '\0';
if (!parseParams(&ptr[1], params, 1024)) {
params[0] = '\0';
rfbLog("httpd: bad parameters in the URL\n");
}
}
/* If we were asked for '/', actually read the file index.vnc */ /* If we were asked for '/', actually read the file index.vnc */
if (strcmp(fname, "/") == 0) { if (strcmp(fname, "/") == 0) {
...@@ -382,6 +399,11 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) ...@@ -382,6 +399,11 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
} else } else
#endif #endif
WriteExact(&cl, "?", 1); WriteExact(&cl, "?", 1);
} else if (compareAndSkip(&ptr, "$PARAMS")) {
if (params[0] != '\0')
WriteExact(httpSock, params, strlen(params));
} else { } else {
if (!compareAndSkip(&ptr, "$$")) if (!compareAndSkip(&ptr, "$$"))
ptr++; ptr++;
...@@ -420,3 +442,96 @@ compareAndSkip(char **ptr, const char *str) ...@@ -420,3 +442,96 @@ compareAndSkip(char **ptr, const char *str)
return FALSE; return FALSE;
} }
/*
* Parse the request tail after the '?' character, and format a sequence
* of <param> tags for inclusion into an HTML page with embedded applet.
*/
static Bool
parseParams(const char *request, char *result, int max_bytes)
{
char param_request[128];
char param_formatted[196];
const char *tail;
char *delim_ptr;
char *value_str;
int cur_bytes, len;
result[0] = '\0';
cur_bytes = 0;
tail = request;
for (;;) {
/* Copy individual "name=value" string into a buffer */
delim_ptr = strchr((char *)tail, '&');
if (delim_ptr == NULL) {
if (strlen(tail) >= sizeof(param_request)) {
return FALSE;
}
strcpy(param_request, tail);
} else {
len = delim_ptr - tail;
if (len >= sizeof(param_request)) {
return FALSE;
}
memcpy(param_request, tail, len);
param_request[len] = '\0';
}
/* Split the request into parameter name and value */
value_str = strchr(&param_request[1], '=');
if (value_str == NULL) {
return FALSE;
}
*value_str++ = '\0';
if (strlen(value_str) == 0) {
return FALSE;
}
/* Validate both parameter name and value */
if (!validateString(param_request) || !validateString(value_str)) {
return FALSE;
}
/* Prepare HTML-formatted representation of the name=value pair */
len = sprintf(param_formatted,
"<PARAM NAME=\"%s\" VALUE=\"%s\">\n",
param_request, value_str);
if (cur_bytes + len + 1 > max_bytes) {
return FALSE;
}
strcat(result, param_formatted);
cur_bytes += len;
/* Go to the next parameter */
if (delim_ptr == NULL) {
break;
}
tail = delim_ptr + 1;
}
return TRUE;
}
/*
* Check if the string consists only of alphanumeric characters, '+'
* signs, underscores, and dots. Replace all '+' signs with spaces.
*/
static Bool
validateString(char *str)
{
char *ptr;
for (ptr = str; *ptr != '\0'; ptr++) {
if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.') {
if (*ptr == '+') {
*ptr = ' ';
} else {
return FALSE;
}
}
}
return TRUE;
}
...@@ -63,7 +63,7 @@ vncEncryptAndStorePasswd(char *passwd, char *fname) ...@@ -63,7 +63,7 @@ vncEncryptAndStorePasswd(char *passwd, char *fname)
/* windows security sux */ /* windows security sux */
#ifndef WIN32 #ifndef WIN32
chmod(fname, S_IRUSR|S_IWUSR); fchmod(fp, S_IRUSR|S_IWUSR);
#endif #endif
/* pad password with nulls */ /* pad password with nulls */
......
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