Fossil SCM

fossil-scm / src / auxwww.c
Blame History Raw 143 lines
1
/*
2
** Copyright (c) 2007 D. Richard Hipp
3
**
4
** This program is free software; you can redistribute it and/or
5
** modify it under the terms of the Simplified BSD License (also
6
** known as the "2-Clause License" or "FreeBSD License".)
7
**
8
** This program is distributed in the hope that it will be useful,
9
** but without any warranty; without even the implied warranty of
10
** merchantability or fitness for a particular purpose.
11
**
12
** Author contact information:
13
** [email protected]
14
** http://www.hwaci.com/drh/
15
**
16
*******************************************************************************
17
**
18
** This file contains code to implement the /aux webpage.
19
**
20
** The /aux webpage acts like a recursive webserver, relaying the
21
** HTTP request to some other component - usually another CGI.
22
**
23
** Before doing the relay, /aux examines the login cookie to see
24
** if the HTTP request is coming from a validaded user, and if so
25
** /aux sets some additional environment variables that the child
26
** CGI script can use. In this way, the child CGI scripts use the
27
** same login system as the main repository, and appear to be
28
** an integrated part of the repository.
29
*/
30
#include "config.h"
31
#include "auxwww.h"
32
#include <assert.h>
33
34
/*
35
** WEBPAGE: aux
36
**
37
** Relay an HTTP request to secondary CGI after first checking the
38
** login credentials and setting auxiliary environment variables
39
** so that the secondary CGI can be aware of the credentials and
40
** capabilities of the Fossil user.
41
**
42
** The /aux page is only functional if the "auxroot: DIR" setting is
43
** found in the CGI script that launched Fossil, or if the "--auxroot DIR"
44
** flag is present when Fossil is lauched using the "server", "ui", or
45
** "http" commands. DIR must be an absolute pathname (relative to the
46
** chroot jail) of the root of the file hierarchy that implements the CGI
47
** functionality. Executable files are CGI. Non-executable files are
48
** static content.
49
**
50
** The path after the /aux is the path to the CGI script or static file
51
** relative to DIR. For security, this path may not contain characters
52
** other than ASCII letters or digits, ".", "-", "/", and "_". If the
53
** "." or "-" characters are present in the path then they may not follow
54
** a "/".
55
*/
56
void aux_page(void){
57
const char *zName = P("name"); /* Path information after /aux */
58
char *zPath = 0; /* Complete path from auxroot */
59
int nRoot; /* Number of bytes in the auxroot name */
60
char *zScript = 0; /* Name of the CGI script */
61
int nScript = 0; /* Bytes in the CGI script name */
62
const char *zFailReason = "???";/* Reason for failure */
63
int i; /* Loop counter */
64
65
if( g.zAuxRoot==0 ){
66
zFailReason = "auxroot is not set";
67
goto aux_not_found;
68
}
69
if( file_is_absolute_path(g.zAuxRoot)==0 ){
70
zFailReason = "auxroot is a relative pathname";
71
goto aux_not_found;
72
}
73
if( zName==0 ){
74
zFailReason = "no path beyond /aux";
75
goto aux_not_found;
76
}
77
if( file_isdir(g.zAuxRoot,ExtFILE)!=1 ){
78
zFailReason = "auxroot is not a directory";
79
goto aux_not_found;
80
}
81
zPath = mprintf("%s/%s", g.zAuxRoot, zName);
82
nRoot = (int)strlen(g.zAuxRoot);
83
if( file_isfile(zPath, ExtFILE) ){
84
nScript = (int)strlen(zPath);
85
zScript = zPath;
86
}else{
87
for(i=nRoot+1; zPath[i]; i++){
88
char c = zPath[i];
89
if( (c=='.' || c=='-') && zPath[i-1]=='/' ){
90
zFailReason = "path element begins with '.' or '-'";
91
goto aux_not_found;
92
}
93
if( !fossil_isalnum(c) && c!='_' && c!='-' && c!='.' ){
94
zFailReason = "illegal character in path";
95
goto aux_not_found;
96
}
97
if( c=='/' ){
98
int isDir, isFile;
99
zPath[i] = 0;
100
isDir = file_isdir(zPath, ExtFILE);
101
isFile = isDir==2 ? file_isfile(zPath, ExtFILE) : 0;
102
zPath[i] = c;
103
if( isDir==0 ){
104
zFailReason = "path does not match any file or script";
105
goto aux_not_found;
106
}
107
if( isFile!=0 ){
108
zScript = mprintf("%.*s", i, zPath);
109
nScript = i;
110
break;
111
}
112
}
113
}
114
}
115
if( nScript==0 ){
116
zFailReason = "path does not match any file or script";
117
goto aux_not_found;
118
}
119
if( !file_isexe(zScript, ExtFILE) ){
120
const char *zMime;
121
/* File is not executable. Must be a regular file. In that case,
122
** disallow extra path elements */
123
if( zPath[nScript]!=0 ){
124
zFailReason = "extra path elements after filename";
125
goto aux_not_found;
126
}
127
zMime = mimetype_from_name(zScript);
128
if( zMime==0 ) zMime = "application/octet-stream";
129
cgi_set_content_type(zMime);
130
blob_read_from_file(cgi_output_blob(), zScript, ExtFILE);
131
return;
132
}
133
/* If we reach this point, that means we are dealing with an executable
134
** file name zScript. Run that file as CGI. */
135
login_check_credentials();
136
137
aux_not_found:
138
fossil_free(zPath);
139
cgi_set_status(404, "Not Found");
140
@ %h(zFailReason)
141
return;
142
}
143

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button