Made the (currently disabled) http download code more secure.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2975 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2008-05-25 22:02:52 +00:00
parent ef8c96667e
commit 5e166cb9ce
3 changed files with 50 additions and 7 deletions

View file

@ -503,7 +503,8 @@ int main(int argc, char **argv)
strcpy(cluster->hostname, DEFAULT_HOSTNAME); strcpy(cluster->hostname, DEFAULT_HOSTNAME);
cluster->buildnumber = build_number(); cluster->buildnumber = build_number();
cluster->maxproxies = -1; cluster->maxproxies = -1;
strcpy(cluster->downloaddir, "id1/");
strcpy(cluster->demodir, "qw/demos/"); strcpy(cluster->demodir, "qw/demos/");
Sys_Printf(cluster, "QTV Build %i.\n", cluster->buildnumber); Sys_Printf(cluster, "QTV Build %i.\n", cluster->buildnumber);

View file

@ -562,8 +562,10 @@ static void HTTPSV_GenerateDemoListing(cluster_t *cluster, oproxy_t *dest)
static void HTTPSV_GenerateDownload(cluster_t *cluster, oproxy_t *dest, char *filename) static void HTTPSV_GenerateDownload(cluster_t *cluster, oproxy_t *dest, char *filename)
{ {
#ifdef ALLOWDOWNLOADS #ifdef ALLOWDOWNLOADS
char fname[256]; char fname[256];
char *s; char link[512];
char *s, *suppliedname;
int len;
if (cluster->allowdownloads) if (cluster->allowdownloads)
#endif #endif
@ -575,8 +577,8 @@ static void HTTPSV_GenerateDownload(cluster_t *cluster, oproxy_t *dest, char *fi
HTTPSV_SendHTMLFooter(cluster, dest); HTTPSV_SendHTMLFooter(cluster, dest);
return; return;
} }
#ifdef ALLOWDOWNLOADS #ifdef ALLOWDOWNLOADS
s = fname; suppliedname = s = fname + strlcpy(fname, cluster->downloaddir, sizeof(fname));
while (*filename > ' ') while (*filename > ' ')
{ {
if (s > fname + sizeof(fname)-4) //4 cos I'm too lazy to work out what the actual number should be if (s > fname + sizeof(fname)-4) //4 cos I'm too lazy to work out what the actual number should be
@ -611,7 +613,38 @@ static void HTTPSV_GenerateDownload(cluster_t *cluster, oproxy_t *dest, char *fi
else else
*s++ = *filename++; *s++ = *filename++;
} }
*s = 0; *s = 0;
if (*suppliedname == '\\' || *suppliedname == '/' || strstr(suppliedname, "..") || suppliedname[1] == ':')
{
HTTPSV_SendHTTPHeader(cluster, dest, "403", "text/html", true);
HTTPSV_SendHTMLHeader(cluster, dest, "Permission denied");
HTMLPRINT("<h1>403: Forbidden</h1>");
HTMLPRINT("<p>");
HTMLprintf(link, sizeof(link), "The filename '%s' names an absolute path.", suppliedname);
Net_ProxySend(cluster, dest, link, strlen(link));
HTMLPRINT("</p>");
return;
}
len = strlen(fname);
if (len > 4)
{
if (!stricmp(link+len-4, ".pak"))
{
HTTPSV_SendHTTPHeader(cluster, dest, "403", "text/html", true);
HTTPSV_SendHTMLHeader(cluster, dest, "Permission denied");
HTMLPRINT("<h1>403: Forbidden</h1>");
HTMLPRINT("<p>");
HTMLprintf(link, sizeof(link), "Pak files may not be downloaded.", suppliedname);
Net_ProxySend(cluster, dest, link, strlen(link));
HTMLPRINT("</p>");
return;
}
}
dest->srcfile = fopen(fname, "rb"); dest->srcfile = fopen(fname, "rb");
if (dest->srcfile) if (dest->srcfile)
@ -622,7 +655,13 @@ static void HTTPSV_GenerateDownload(cluster_t *cluster, oproxy_t *dest, char *fi
{ {
HTTPSV_SendHTTPHeader(cluster, dest, "404", "text/html", true); HTTPSV_SendHTTPHeader(cluster, dest, "404", "text/html", true);
HTTPSV_SendHTMLHeader(cluster, dest, "File not found"); HTTPSV_SendHTMLHeader(cluster, dest, "File not found");
HTMLPRINT("<h1>404: File not found</h1>"); HTMLPRINT("<h1>404: File not found</h1>");
HTMLPRINT("<p>");
HTMLprintf(link, sizeof(link), "The file '%s' could not be found on this server", fname);
Net_ProxySend(cluster, dest, link, strlen(link));
HTMLPRINT("</p>");
HTTPSV_SendHTMLFooter(cluster, dest); HTTPSV_SendHTMLFooter(cluster, dest);
} }
#endif #endif

View file

@ -629,6 +629,7 @@ struct cluster_s {
char hostname[256]; char hostname[256];
char master[MAX_QPATH]; char master[MAX_QPATH];
char demodir[MAX_QPATH]; char demodir[MAX_QPATH];
char downloaddir[MAX_QPATH]; //must be slash terminated, or empty.
qboolean chokeonnotupdated; qboolean chokeonnotupdated;
qboolean lateforward; qboolean lateforward;
qboolean notalking; qboolean notalking;
@ -636,6 +637,8 @@ struct cluster_s {
qboolean allownqclients; //nq clients require no challenge qboolean allownqclients; //nq clients require no challenge
qboolean nouserconnects; //prohibit users from connecting to new streams. qboolean nouserconnects; //prohibit users from connecting to new streams.
qboolean allowdownloads;
int maxviewers; int maxviewers;
int buildnumber; int buildnumber;