From 6b178b46ef52fc146fee566e9bdd12929d3ad0a3 Mon Sep 17 00:00:00 2001 From: Jacob Appelbaum Date: Sun, 7 Dec 2008 01:21:19 +0000 Subject: [PATCH] New DirPortFrontPage option that takes an html file and publishes it as "/" on the DirPort. Now relay operators can provide a disclaimer without needin to set up a separate webserver. There's a sample disclaimer in contrib/tor-exit-notice.html. svn:r17500 --- ChangeLog | 6 ++++++ doc/tor.1.in | 7 +++++++ src/config/torrc.sample.in | 4 ++++ src/or/config.c | 20 ++++++++++++++++++++ src/or/directory.c | 22 ++++++++++++++++++++++ src/or/or.h | 5 +++++ src/or/test.c | 1 - 7 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b87579d200..5d37ced6a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ Changes in version 0.2.1.8-alpha - 2008-12-06 + o Major feature: + - New DirPortFrontPage option that takes an html file and publishes it as + "/" on the DirPort. Now relay operators can provide a disclaimer without + needing to set up a separate webserver. There's a sample disclaimer + in contrib/tor-exit-notice.html. + o Major bugfixes: - Fix a DOS opportunity during the voting signature collection process at directory authorities. Spotted by rovv. Bugfix on 0.2.0.x. diff --git a/doc/tor.1.in b/doc/tor.1.in index 67a7db4f9f..237d0ed328 100644 --- a/doc/tor.1.in +++ b/doc/tor.1.in @@ -1044,6 +1044,13 @@ probably do not want to set this option. Please coordinate with the other admins at tor-ops@freehaven.net if you think you should be a directory. .LP .TP +\fBDirPortFrontPage \fIFILENAME\fP +When this option is set, it takes an html file and publishes it as "/" on +the DirPort. Now relay operators can provide a disclaimer without needing +to set up a separate webserver. There's a sample disclaimer in +contrib/tor-exit-notice.html. +.LP +.TP \fBV1AuthoritativeDirectory \fR\fB0\fR|\fB1\fR\fP When this option is set in addition to \fBAuthoritativeDirectory\fP, Tor generates version 1 directory and running-routers documents (for legacy diff --git a/src/config/torrc.sample.in b/src/config/torrc.sample.in index 0c71c9688d..20322caec9 100644 --- a/src/config/torrc.sample.in +++ b/src/config/torrc.sample.in @@ -109,6 +109,10 @@ SocksListenAddress 127.0.0.1 # accept connections only from localhost ## to make this work. #DirListenAddress 0.0.0.0:9091 +## Uncomment this to return an arbitrary blob of html on your DirPort. You may +## wish to use this blob of html to inform clients about your Tor server. +#DirPortFrontPage /etc/tor/exit-notice.html + ## Uncomment this if you run more than one Tor server, and add the ## nickname of each Tor server you control, even if they're on different ## networks. You declare it here so Tor clients can avoid using more than diff --git a/src/or/config.c b/src/or/config.c index a017d1e919..f08a55dd46 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -184,6 +184,7 @@ static config_var_t _option_vars[] = { OBSOLETE("DirFetchPeriod"), V(DirPolicy, LINELIST, NULL), V(DirPort, UINT, "0"), + V(DirPortFrontPage, STRING, NULL), OBSOLETE("DirPostPeriod"), #ifdef ENABLE_GEOIP_STATS V(DirRecordUsageByCountry, BOOL, "0"), @@ -559,6 +560,7 @@ static config_var_description_t options_description[] = { /* === directory cache options */ { "DirPort", "Serve directory information from this port, and act as a " "directory cache." }, + { "DirPortFrontPage", "Serve a static html disclaimer on DirPort." }, { "DirListenAddress", "Bind to this address to listen for connections from " "clients and servers, instead of the default 0.0.0.0:DirPort." }, { "DirPolicy", "Set a policy to limit who can connect to the directory " @@ -754,6 +756,15 @@ static char *torrc_fname = NULL; static or_state_t *global_state = NULL; /** Configuration Options set by command line. */ static config_line_t *global_cmdline_options = NULL; +/** Contents of most recently read DirPortFrontPage option file. */ +static char *global_dirfrontpagecontents = NULL; + +/** Return the contents of our frontpage string, or NULL if not configured. */ +const char * +get_dirportfrontpage(void) +{ + return global_dirfrontpagecontents; +} /** Allocate an empty configuration object of a given format type. */ static void * @@ -849,6 +860,7 @@ config_free_all(void) } tor_free(torrc_fname); tor_free(_version); + tor_free(global_dirfrontpagecontents); } /** If options->SafeLogging is on, return a not very useful string, @@ -1410,6 +1422,14 @@ options_act(or_options_t *old_options) } } + /* Load the webpage we're going to serve everytime someone asks for '/' on + our DirPort. */ + tor_free(global_dirfrontpagecontents); + if (options->DirPortFrontPage) { + global_dirfrontpagecontents = + read_file_to_str(options->DirPortFrontPage, 0, NULL); + } + return 0; } diff --git a/src/or/directory.c b/src/or/directory.c index 5bd85bab7c..14470060a0 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -88,6 +88,7 @@ static void directory_initiate_command_rend(const char *address, * kind of document we serve? */ #define FULL_DIR_CACHE_LIFETIME (60*60) #define RUNNINGROUTERS_CACHE_LIFETIME (20*60) +#define DIRPORTFRONTPAGE_CACHE_LIFETIME (20*60) #define NETWORKSTATUS_CACHE_LIFETIME (5*60) #define ROUTERDESC_CACHE_LIFETIME (30*60) #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60) @@ -2473,6 +2474,27 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, url_len -= 2; } + if (!strcmp(url,"/tor/")) { + const char *frontpage = get_dirportfrontpage(); + + if (frontpage) { + dlen = strlen(frontpage); + /* Lets return a disclaimer, users shouldn't use V1 anymore */ + if (global_write_bucket_low(TO_CONN(conn), dlen, 1)) { + log_info(LD_DIRSERV, + "Client asked for DirPortFrontPage content, but we've been " + "writing too many bytes lately. Sending 503 Dir busy."); + write_http_status_line(conn, 503, "Directory busy, try again later"); + goto done; + } + note_request(url, dlen); + write_http_response_header_impl(conn, dlen, "text/html", "identity", + NULL, DIRPORTFRONTPAGE_CACHE_LIFETIME); + connection_write_to_buf(frontpage, dlen, TO_CONN(conn)); + goto done; + } + } + if (!strcmp(url,"/tor/") || !strcmp(url,"/tor/dir")) { /* v1 dir fetch */ cached_dir_t *d = dirserv_get_directory(); diff --git a/src/or/or.h b/src/or/or.h index 254fb60b62..d7459033f5 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2402,6 +2402,10 @@ typedef struct { char *ServerDNSResolvConfFile; /**< If provided, we configure our internal * resolver from the file here rather than from * /etc/resolv.conf (Unix) or the registry (Windows). */ + char *DirPortFrontPage; /**< This is a full path to a file with an html + disclaimer. This allows a server administrator to show + that they're running Tor and anyone visiting their server + will know this without any specialized knowledge. */ /** Boolean: if set, we start even if our resolv.conf file is missing * or broken. */ int ServerDNSAllowBrokenResolvConf; @@ -2805,6 +2809,7 @@ typedef enum setopt_err_t { SETOPT_ERR_SETTING = -4, } setopt_err_t; +const char *get_dirportfrontpage(void); or_options_t *get_options(void); int set_options(or_options_t *new_val, char **msg); void config_free_all(void); diff --git a/src/or/test.c b/src/or/test.c index c0fa05e2c8..4cddff44a5 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1916,7 +1916,6 @@ test_util_smartlist_strings(void) test_eq((int)sz, 40); tor_free(cp); - done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));