please unblock tor 0.2.0.32-1
Hi,
I would like to get tor 0.2.0.32-1 into lenny.
It's a new upstream version of the current stable tree. That means it
only saw bugfixes and no new features.
At least one of the fixes is a security fix in the traditional sense:
Tor didn't properly drop supplementary group entries on startup. See
the changelog for a list of other bug fixes.
I have attached a somewhat cleaned upstream diff, i.e. only including
files that influence what ends up in the .deb - not stuff like the
MacOSX packaging, and the full .deb interdiff.
--
| .''`. ** Debian GNU/Linux **
Peter Palfrader | : :' : The universal
http://www.palfrader.org/ | `. `' Operating System
| `- http://www.debian.org/
diff -Nur tor-0.2.0.31/ChangeLog tor-0.2.0.32/ChangeLog
--- tor-0.2.0.31/ChangeLog 2008-09-03 23:27:18.000000000 +0200
+++ tor-0.2.0.32/ChangeLog 2008-11-20 23:33:46.000000000 +0100
@@ -1,4 +1,73 @@
+Changes in version 0.2.0.32 - 2008-11-20
+ o Security fixes:
+ - The "User" and "Group" config options did not clear the
+ supplementary group entries for the Tor process. The "User" option
+ is now more robust, and we now set the groups to the specified
+ user's primary group. The "Group" option is now ignored. For more
+ detailed logging on credential switching, set CREDENTIAL_LOG_LEVEL
+ in common/compat.c to LOG_NOTICE or higher. Patch by Jacob Appelbaum
+ and Steven Murdoch. Bugfix on 0.0.2pre14. Fixes bug 848 and 857.
+ - The "ClientDNSRejectInternalAddresses" config option wasn't being
+ consistently obeyed: if an exit relay refuses a stream because its
+ exit policy doesn't allow it, we would remember what IP address
+ the relay said the destination address resolves to, even if it's
+ an internal IP address. Bugfix on 0.2.0.7-alpha; patch by rovv.
+
+ 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.
+
+ o Major bugfixes (hidden services):
+ - When fetching v0 and v2 rendezvous service descriptors in parallel,
+ we were failing the whole hidden service request when the v0
+ descriptor fetch fails, even if the v2 fetch is still pending and
+ might succeed. Similarly, if the last v2 fetch fails, we were
+ failing the whole hidden service request even if a v0 fetch is
+ still pending. Fixes bug 814. Bugfix on 0.2.0.10-alpha.
+ - When extending a circuit to a hidden service directory to upload a
+ rendezvous descriptor using a BEGIN_DIR cell, almost 1/6 of all
+ requests failed, because the router descriptor has not been
+ downloaded yet. In these cases, do not attempt to upload the
+ rendezvous descriptor, but wait until the router descriptor is
+ downloaded and retry. Likewise, do not attempt to fetch a rendezvous
+ descriptor from a hidden service directory for which the router
+ descriptor has not yet been downloaded. Fixes bug 767. Bugfix
+ on 0.2.0.10-alpha.
+
+ o Minor bugfixes:
+ - Fix several infrequent memory leaks spotted by Coverity.
+ - When testing for libevent functions, set the LDFLAGS variable
+ correctly. Found by Riastradh.
+ - Avoid a bug where the FastFirstHopPK 0 option would keep Tor from
+ bootstrapping with tunneled directory connections. Bugfix on
+ 0.1.2.5-alpha. Fixes bug 797. Found by Erwin Lam.
+ - When asked to connect to A.B.exit:80, if we don't know the IP for A
+ and we know that server B rejects most-but-not all connections to
+ port 80, we would previously reject the connection. Now, we assume
+ the user knows what they were asking for. Fixes bug 752. Bugfix
+ on 0.0.9rc5. Diagnosed by BarkerJr.
+ - If we overrun our per-second write limits a little, count this as
+ having used up our write allocation for the second, and choke
+ outgoing directory writes. Previously, we had only counted this when
+ we had met our limits precisely. Fixes bug 824. Patch from by rovv.
+ Bugfix on 0.2.0.x (??).
+ - Remove the old v2 directory authority 'lefkada' from the default
+ list. It has been gone for many months.
+ - Stop doing unaligned memory access that generated bus errors on
+ sparc64. Bugfix on 0.2.0.10-alpha. Fixes bug 862.
+ - Make USR2 log-level switch take effect immediately. Bugfix on
+ 0.1.2.8-beta.
+
+ o Minor bugfixes (controller):
+ - Make DNS resolved events into "CLOSED", not "FAILED". Bugfix on
+ 0.1.2.5-alpha. Fix by Robert Hogan. Resolves bug 807.
+
+
Changes in version 0.2.0.31 - 2008-09-03
+ Tor 0.2.0.31 addresses two potential anonymity issues, starts to fix
+ a big bug we're seeing where in rare cases traffic from one Tor stream
+ gets mixed into another stream, and fixes a variety of smaller issues.
+
o Major bugfixes:
- Make sure that two circuits can never exist on the same connection
with the same circuit ID, even if one is marked for close. This
@@ -49,6 +118,9 @@
Changes in version 0.2.0.29-rc - 2008-07-08
+ Tor 0.2.0.29-rc fixes two big bugs with using bridges, fixes more
+ hidden-service performance bugs, and fixes a bunch of smaller bugs.
+
o Major bugfixes:
- If you have more than one bridge but don't know their keys,
you would only launch a request for the descriptor of the first one
diff -Nur tor-0.2.0.31/configure tor-0.2.0.32/configure
--- tor-0.2.0.31/configure 2008-09-03 23:23:05.000000000 +0200
+++ tor-0.2.0.32/configure 2008-11-20 23:34:53.000000000 +0100
@@ -2100,7 +2100,7 @@
# Define the identity of the package.
PACKAGE=tor
- VERSION=0.2.0.31
+ VERSION=0.2.0.32
cat >>confdefs.h <<_ACEOF
@@ -6533,7 +6533,7 @@
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LIBS="-levent $TOR_LIB_WS32 $LIBS"
-LDFLAGS="$TOR_LDFLAGS_libevent $LIBS"
+LDFLAGS="$TOR_LDFLAGS_libevent $LDFLAGS"
CPPFLAGS="$TOR_CPPFLAGS_libevent $CPPFLAGS"
@@ -18919,6 +18919,103 @@
+# Check if we have getresuid and getresgid
+
+
+for ac_func in getresuid getresgid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
# Check for gethostbyname_r in all its glorious incompatible versions.
# (This logic is based on that in Python's configure.in)
diff -Nur tor-0.2.0.31/configure.in tor-0.2.0.32/configure.in
--- tor-0.2.0.31/configure.in 2008-09-02 02:04:50.000000000 +0200
+++ tor-0.2.0.32/configure.in 2008-11-20 23:34:31.000000000 +0100
@@ -1,11 +1,11 @@
-dnl $Id: configure.in 16733 2008-09-02 00:04:50Z arma $
+dnl $Id: configure.in 17344 2008-11-20 22:34:30Z arma $
dnl Copyright (c) 2001-2004, Roger Dingledine
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
dnl Copyright (c) 2007-2008, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_INIT
-AM_INIT_AUTOMAKE(tor, 0.2.0.31)
+AM_INIT_AUTOMAKE(tor, 0.2.0.32)
AM_CONFIG_HEADER(orconfig.h)
AC_CANONICAL_HOST
@@ -254,7 +254,7 @@
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LIBS="-levent $TOR_LIB_WS32 $LIBS"
-LDFLAGS="$TOR_LDFLAGS_libevent $LIBS"
+LDFLAGS="$TOR_LDFLAGS_libevent $LDFLAGS"
CPPFLAGS="$TOR_CPPFLAGS_libevent $CPPFLAGS"
AC_CHECK_FUNCS(event_get_version event_get_method event_set_log_callback)
LIBS="$save_LIBS"
@@ -616,6 +616,9 @@
AC_DEFINE_UNQUOTED(LOGFACILITY,$syslog_facility,[name of the syslog facility])
AC_SUBST(LOGFACILITY)
+# Check if we have getresuid and getresgid
+AC_CHECK_FUNCS(getresuid getresgid)
+
# Check for gethostbyname_r in all its glorious incompatible versions.
# (This logic is based on that in Python's configure.in)
AH_TEMPLATE(HAVE_GETHOSTBYNAME_R,
diff -Nur tor-0.2.0.31/contrib/linux-tor-prio.sh tor-0.2.0.32/contrib/linux-tor-prio.sh
diff -Nur tor-0.2.0.31/contrib/osx/TorBundleInfo.plist.in tor-0.2.0.32/contrib/osx/TorBundleInfo.plist.in
diff -Nur tor-0.2.0.31/contrib/osx/TorPostflight tor-0.2.0.32/contrib/osx/TorPostflight
diff -Nur tor-0.2.0.31/contrib/rc.subr tor-0.2.0.32/contrib/rc.subr
diff -Nur tor-0.2.0.31/contrib/tor-mingw.nsi.in tor-0.2.0.32/contrib/tor-mingw.nsi.in
diff -Nur tor-0.2.0.31/contrib/tor.sh tor-0.2.0.32/contrib/tor.sh
diff -Nur tor-0.2.0.31/contrib/tor.sh.in tor-0.2.0.32/contrib/tor.sh.in
diff -Nur tor-0.2.0.31/contrib/torctl tor-0.2.0.32/contrib/torctl
diff -Nur tor-0.2.0.31/contrib/torctl.in tor-0.2.0.32/contrib/torctl.in
[All not relevant]
diff -Nur tor-0.2.0.31/doc/tor.1.in tor-0.2.0.32/doc/tor.1.in
--- tor-0.2.0.31/doc/tor.1.in 2008-05-13 00:56:44.000000000 +0200
+++ tor-0.2.0.32/doc/tor.1.in 2008-11-12 11:47:38.000000000 +0100
@@ -259,10 +259,6 @@
(Default: 0)
.LP
.TP
-\fBGroup \fR\fIGID\fP
-On startup, setgid to this group.
-.LP
-.TP
\fBHttpProxy\fR \fIhost\fR[:\fIport\fR]\fP
Tor will make all its directory requests through this host:port
(or host:80 if port is not specified),
@@ -345,7 +341,7 @@
.LP
.TP
\fBUser \fR\fIUID\fP
-On startup, setuid to this user.
+On startup, setuid to this user and setgid to their primary group.
.LP
.TP
\fBHardwareAccel \fR\fB0\fR|\fB1\fP
@@ -663,11 +659,14 @@
.LP
.TP
\fBFastFirstHopPK \fR\fB0\fR|\fB1\fR\fP
-When this option is enabled and we aren't running as a server, Tor
-skips the public key step for the first hop of creating circuits. This is
-safe since we have already used TLS to authenticate the server and to
-establish forward-secure keys. Turning this option off makes circuit
-building slower.
+When this option is disabled, Tor uses the public key step for the first
+hop of creating circuits. Skipping it is generally safe since we have
+already used TLS to authenticate the relay and to establish forward-secure
+keys. Turning this option off makes circuit building slower.
+
+Note that Tor will always use the public key step for the first hop if
+it's operating as a relay, and it will never use the public key step if
+it doesn't yet know the onion key of the first hop.
(Default: 1)
.LP
.TP
diff -Nur tor-0.2.0.31/orconfig.h.in tor-0.2.0.32/orconfig.h.in
--- tor-0.2.0.31/orconfig.h.in 2008-09-03 23:23:46.000000000 +0200
+++ tor-0.2.0.32/orconfig.h.in 2008-11-20 23:35:26.000000000 +0100
@@ -72,6 +72,12 @@
/* Define this if gethostbyname_r takes 6 arguments */
#undef HAVE_GETHOSTBYNAME_R_6_ARG
+/* Define to 1 if you have the `getresgid' function. */
+#undef HAVE_GETRESGID
+
+/* Define to 1 if you have the `getresuid' function. */
+#undef HAVE_GETRESUID
+
/* Define to 1 if you have the `getrlimit' function. */
#undef HAVE_GETRLIMIT
diff -Nur tor-0.2.0.31/src/common/compat.c tor-0.2.0.32/src/common/compat.c
--- tor-0.2.0.31/src/common/compat.c 2008-04-23 23:03:35.000000000 +0200
+++ tor-0.2.0.32/src/common/compat.c 2008-11-21 00:06:37.000000000 +0100
@@ -871,62 +871,220 @@
return 0;
}
-/** Call setuid and setgid to run as <b>user</b>:<b>group</b>. Return 0 on
- * success. On failure, log and return -1.
+/** Log details of current user and group credentials. Return 0 on
+ * success. Logs and return -1 on failure.
+ */
+static int
+log_credential_status(void)
+{
+#define CREDENTIAL_LOG_LEVEL LOG_INFO
+#ifndef MS_WINDOWS
+ /* Real, effective and saved UIDs */
+ uid_t ruid, euid, suid;
+ /* Read, effective and saved GIDs */
+ gid_t rgid, egid, sgid;
+ /* Supplementary groups */
+ gid_t sup_gids[NGROUPS_MAX + 1];
+ /* Number of supplementary groups */
+ int ngids;
+
+ /* log UIDs */
+#ifdef HAVE_GETRESUID
+ if (getresuid(&ruid, &euid, &suid) != 0 ) {
+ log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno));
+ return -1;
+ } else {
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
+ "UID is %u (real), %u (effective), %u (saved)", ruid, euid, suid);
+ }
+#else
+ /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
+ ruid = getuid();
+ euid = geteuid();
+ (void)suid;
+
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
+ "UID is %u (real), %u (effective), unknown (saved)", ruid, euid);
+#endif
+
+ /* log GIDs */
+#ifdef HAVE_GETRESGID
+ if (getresgid(&rgid, &egid, &sgid) != 0 ) {
+ log_warn(LD_GENERAL, "Error getting changed GIDs: %s", strerror(errno));
+ return -1;
+ } else {
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
+ "GID is %u (real), %u (effective), %u (saved)", rgid, egid, sgid);
+ }
+#else
+ /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
+ rgid = getgid();
+ egid = getegid();
+ (void)sgid;
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
+ "GID is %u (real), %u (effective), unknown (saved)", rgid, egid);
+#endif
+
+ /* log supplementary groups */
+ if ((ngids = getgroups(NGROUPS_MAX + 1, sup_gids)) < 0) {
+ log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s",
+ strerror(errno));
+ return -1;
+ } else {
+ int i;
+ char *strgid;
+ char *s = NULL;
+ int formatting_error = 0;
+ smartlist_t *elts = smartlist_create();
+
+ for (i = 0; i<ngids; i++) {
+ strgid = tor_malloc(11);
+ if (tor_snprintf(strgid, 11, "%u", (unsigned)sup_gids[i]) == -1) {
+ log_warn(LD_GENERAL, "Error printing supplementary GIDs");
+ formatting_error = 1;
+ goto error;
+ }
+ smartlist_add(elts, strgid);
+ }
+
+ s = smartlist_join_strings(elts, " ", 0, NULL);
+
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Supplementary groups are: %s",s);
+
+ error:
+ tor_free(s);
+ SMARTLIST_FOREACH(elts, char *, cp,
+ {
+ tor_free(cp);
+ });
+ smartlist_free(elts);
+
+ if (formatting_error)
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+/** Call setuid and setgid to run as <b>user</b> and switch to their
+ * primary group. Return 0 on success. On failure, log and return -1.
*/
int
-switch_id(const char *user, const char *group)
+switch_id(const char *user)
{
#ifndef MS_WINDOWS
struct passwd *pw = NULL;
- struct group *gr = NULL;
+ uid_t old_uid;
+ gid_t old_gid;
+ static int have_already_switched_id = 0;
- if (user) {
- pw = getpwnam(user);
- if (pw == NULL) {
- log_warn(LD_CONFIG,"User '%s' not found.", user);
- return -1;
- }
+ tor_assert(user);
+
+ if (have_already_switched_id)
+ return 0;
+
+ /* Log the initial credential state */
+ if (log_credential_status())
+ return -1;
+
+ log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Changing user and groups");
+
+ /* Get old UID/GID to check if we changed correctly */
+ old_uid = getuid();
+ old_gid = getgid();
+
+ /* Lookup the user and group information, if we have a problem, bail out. */
+ pw = getpwnam(user);
+ if (pw == NULL) {
+ log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
+ return -1;
}
- /* switch the group first, while we still have the privileges to do so */
- if (group) {
- gr = getgrnam(group);
- if (gr == NULL) {
- log_warn(LD_CONFIG,"Group '%s' not found.", group);
- return -1;
- }
+ /* Properly switch egid,gid,euid,uid here or bail out */
+ if (setgroups(1, &pw->pw_gid)) {
+ log_warn(LD_GENERAL, "Error setting groups to gid %d: \"%s\". "
+ "If you set the \"User\" option, you must start Tor as root.",
+ (int)pw->pw_gid, strerror(errno));
+ return -1;
+ }
- if (setgid(gr->gr_gid) != 0) {
- log_warn(LD_GENERAL,"Error setting to configured GID: %s",
- strerror(errno));
+ if (setegid(pw->pw_gid)) {
+ log_warn(LD_GENERAL, "Error setting egid to %d: %s",
+ (int)pw->pw_gid, strerror(errno));
+ return -1;
+ }
+
+ if (setgid(pw->pw_gid)) {
+ log_warn(LD_GENERAL, "Error setting gid to %d: %s",
+ (int)pw->pw_gid, strerror(errno));
+ return -1;
+ }
+
+ if (setuid(pw->pw_uid)) {
+ log_warn(LD_GENERAL, "Error setting configured uid to %s (%d): %s",
+ user, (int)pw->pw_uid, strerror(errno));
+ return -1;
+ }
+
+ if (seteuid(pw->pw_uid)) {
+ log_warn(LD_GENERAL, "Error setting configured euid to %s (%d): %s",
+ user, (int)pw->pw_uid, strerror(errno));
+ return -1;
+ }
+
+ /* This is how OpenBSD rolls:
+ if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) ||
+ setgid(pw->pw_gid) || setuid(pw->pw_uid) || seteuid(pw->pw_uid)) {
+ setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) {
+ log_warn(LD_GENERAL, "Error setting configured UID/GID: %s",
+ strerror(errno));
+ return -1;
+ }
+ */
+
+ /* We've properly switched egid, gid, euid, uid, and supplementary groups if
+ * we're here. */
+
+#if !defined(CYGWIN) && !defined(__CYGWIN__)
+ /* If we tried to drop privilege to a group/user other than root, attempt to
+ * restore root (E)(U|G)ID, and abort if the operation succeeds */
+
+ /* Only check for privilege dropping if we were asked to be non-root */
+ if (pw->pw_uid) {
+ /* Try changing GID/EGID */
+ if (pw->pw_gid != old_gid &&
+ (setgid(old_gid) != -1 || setegid(old_gid) != -1)) {
+ log_warn(LD_GENERAL, "Was able to restore group credentials even after "
+ "switching GID: this means that the setgid code didn't work.");
return -1;
}
- } else if (user) {
- if (setgid(pw->pw_gid) != 0) {
- log_warn(LD_GENERAL,"Error setting to user GID: %s", strerror(errno));
+
+ /* Try changing UID/EUID */
+ if (pw->pw_uid != old_uid &&
+ (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) {
+ log_warn(LD_GENERAL, "Was able to restore user credentials even after "
+ "switching UID: this means that the setuid code didn't work.");
return -1;
}
}
+#endif
- /* now that the group is switched, we can switch users and lose
- privileges */
- if (user) {
- if (setuid(pw->pw_uid) != 0) {
- log_warn(LD_GENERAL,"Error setting UID: %s", strerror(errno));
- return -1;
- }
+ /* Check what really happened */
+ if (log_credential_status()) {
+ return -1;
}
+ have_already_switched_id = 1; /* mark success so we never try again */
return 0;
+
#else
(void)user;
- (void)group;
-#endif
log_warn(LD_CONFIG,
- "User or group specified, but switching users is not supported.");
+ "User specified but switching users is unsupported on your OS.");
return -1;
+#endif
}
#ifdef HAVE_PWD_H
diff -Nur tor-0.2.0.31/src/common/compat.h tor-0.2.0.32/src/common/compat.h
--- tor-0.2.0.31/src/common/compat.h 2008-07-16 01:45:58.000000000 +0200
+++ tor-0.2.0.32/src/common/compat.h 2008-11-12 11:47:37.000000000 +0100
@@ -463,7 +463,7 @@
typedef unsigned long rlim_t;
#endif
int set_max_file_descriptors(rlim_t limit, int *max);
-int switch_id(const char *user, const char *group);
+int switch_id(const char *user);
#ifdef HAVE_PWD_H
char *get_user_homedir(const char *username);
#endif
diff -Nur tor-0.2.0.31/src/common/log.c tor-0.2.0.32/src/common/log.c
--- tor-0.2.0.31/src/common/log.c 2008-03-16 23:08:00.000000000 +0100
+++ tor-0.2.0.32/src/common/log.c 2008-11-20 23:14:26.000000000 +0100
@@ -701,6 +701,7 @@
for (lf = logfiles; lf; lf=lf->next) {
lf->min_loglevel = LOG_DEBUG;
}
+ _log_global_min_severity = get_min_log_level();
UNLOCK_LOGS();
}
diff -Nur tor-0.2.0.31/src/or/buffers.c tor-0.2.0.32/src/or/buffers.c
--- tor-0.2.0.31/src/or/buffers.c 2008-08-20 07:22:00.000000000 +0200
+++ tor-0.2.0.32/src/or/buffers.c 2008-11-20 23:14:26.000000000 +0100
@@ -966,7 +966,7 @@
return 1;
result = var_cell_new(length);
result->command = command;
- result->circ_id = ntohs(*(uint16_t*)hdr);
+ result->circ_id = ntohs(get_uint16(hdr));
buf_remove_from_front(buf, VAR_CELL_HEADER_SIZE);
peek_from_buf(result->payload, length, buf);
diff -Nur tor-0.2.0.31/src/or/circuitbuild.c tor-0.2.0.32/src/or/circuitbuild.c
--- tor-0.2.0.31/src/or/circuitbuild.c 2008-09-02 00:25:03.000000000 +0200
+++ tor-0.2.0.32/src/or/circuitbuild.c 2008-09-23 23:00:43.000000000 +0200
@@ -541,23 +541,20 @@
return 1;
}
-/** Return true iff we should send a create_fast cell to build a circuit
- * starting at <b>router</b>. (If <b>router</b> is NULL, we don't have
- * information on the router, so assume true.) */
+/** Return true iff we should send a create_fast cell to start building a given
+ * circuit */
static INLINE int
-should_use_create_fast_for_router(routerinfo_t *router,
- origin_circuit_t *circ)
+should_use_create_fast_for_circuit(origin_circuit_t *circ)
{
or_options_t *options = get_options();
+ tor_assert(circ->cpath);
+ tor_assert(circ->cpath->extend_info);
- if (!options->FastFirstHopPK) /* create_fast is disabled */
- return 0;
- if (router && router->platform &&
- !tor_version_as_new_as(router->platform, "0.1.0.6-rc")) {
- /* known not to work */
- return 0;
- }
- if (server_mode(options) && circ->cpath->extend_info->onion_key) {
+ if (!circ->cpath->extend_info->onion_key)
+ return 1; /* our hand is forced: only a create_fast will work. */
+ if (!options->FastFirstHopPK)
+ return 0; /* we prefer to avoid create_fast */
+ if (server_mode(options)) {
/* We're a server, and we know an onion key. We can choose.
* Prefer to blend in. */
return 0;
@@ -593,14 +590,9 @@
log_debug(LD_CIRC,"First skin; sending create cell.");
router = router_get_by_digest(circ->_base.n_conn->identity_digest);
- fast = should_use_create_fast_for_router(router, circ);
- if (!fast && !circ->cpath->extend_info->onion_key) {
- log_warn(LD_CIRC,
- "Can't send create_fast, but have no onion key. Failing.");
- return - END_CIRC_REASON_INTERNAL;
- }
+ fast = should_use_create_fast_for_circuit(circ);
if (!fast) {
- /* We are an OR, or we are connecting to an old Tor: we should
+ /* We are an OR and we know the right onion key: we should
* send an old slow create cell.
*/
cell_type = CELL_CREATE;
diff -Nur tor-0.2.0.31/src/or/config.c tor-0.2.0.32/src/or/config.c
--- tor-0.2.0.31/src/or/config.c 2008-09-02 00:06:47.000000000 +0200
+++ tor-0.2.0.32/src/or/config.c 2008-11-12 11:47:36.000000000 +0100
@@ -204,7 +204,7 @@
V(GeoIPFile, STRING,
SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
#endif
- V(Group, STRING, NULL),
+ OBSOLETE("Group"),
V(HardwareAccel, BOOL, "0"),
V(HashedControlPassword, LINELIST, NULL),
V(HidServDirectoryV2, BOOL, "0"),
@@ -391,7 +391,6 @@
/* { "FastFirstHopPK", "" }, */
/* FetchServerDescriptors, FetchHidServDescriptors,
* FetchUselessDescriptors */
- { "Group", "On startup, setgid to this group." },
{ "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
"when it can." },
/* HashedControlPassword */
@@ -837,8 +836,6 @@
"719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
"tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
"86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
- "lefkada orport=443 "
- "140.247.60.64:80 38D4 F5FC F7B1 0232 28B8 95EA 56ED E7D5 CCDC AF32",
"dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
"194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
"Tonga orport=443 bridge no-v2 82.94.251.206:80 "
@@ -1033,13 +1030,10 @@
#endif
/* Setuid/setgid as appropriate */
- if (options->User || options->Group) {
- /* XXXX021 We should only do this the first time through, not on
- * every setconf. */
- if (switch_id(options->User, options->Group) != 0) {
+ if (options->User) {
+ if (switch_id(options->User) != 0) {
/* No need to roll back, since you can't change the value. */
- *msg = tor_strdup("Problem with User or Group value. "
- "See logs for details.");
+ *msg = tor_strdup("Problem with User value. See logs for details.");
goto done;
}
}
@@ -1870,9 +1864,9 @@
result->value = tor_strdup("");
break;
case CONFIG_TYPE_OBSOLETE:
- log_warn(LD_CONFIG,
- "You asked me for the value of an obsolete config option '%s'.",
- key);
+ log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
+ "You asked me for the value of an obsolete config option '%s'.",
+ key);
tor_free(result->key);
tor_free(result);
return NULL;
diff -Nur tor-0.2.0.31/src/or/connection.c tor-0.2.0.32/src/or/connection.c
--- tor-0.2.0.31/src/or/connection.c 2008-06-11 04:04:59.000000000 +0200
+++ tor-0.2.0.32/src/or/connection.c 2008-11-12 11:47:37.000000000 +0100
@@ -479,8 +479,13 @@
* failed: forget about this router, and maybe try again. */
connection_dir_request_failed(dir_conn);
}
- if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
- rend_client_desc_here(dir_conn->rend_query); /* give it a try */
+ if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
+ /* Give it a try. However, there is no re-fetching for v0 rend
+ * descriptors; if the response is empty or the descriptor is
+ * unusable, close pending connections (unless a v2 request is
+ * still in progress). */
+ rend_client_desc_trynow(dir_conn->rend_query, 0);
+ }
/* If we were trying to fetch a v2 rend desc and did not succeed,
* retry as needed. (If a fetch is successful, the connection state
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that
@@ -1718,7 +1723,7 @@
tor_assert(seconds_elapsed >= 0);
write_buckets_empty_last_second =
- global_relayed_write_bucket == 0 || global_write_bucket == 0;
+ global_relayed_write_bucket <= 0 || global_write_bucket <= 0;
/* refill the global buckets */
connection_bucket_refill_helper(&global_read_bucket,
diff -Nur tor-0.2.0.31/src/or/connection_edge.c tor-0.2.0.32/src/or/connection_edge.c
--- tor-0.2.0.31/src/or/connection_edge.c 2008-09-02 00:53:16.000000000 +0200
+++ tor-0.2.0.32/src/or/connection_edge.c 2008-09-29 08:49:32.000000000 +0200
@@ -696,6 +696,8 @@
MAP_DEL_CURRENT(address);
}
} STRMAP_FOREACH_END;
+
+ tor_free(suffix);
}
/** Remove all entries from the addressmap that were set via the
@@ -1366,8 +1368,7 @@
map_expires);
connection_mark_unattached_ap(conn,
END_STREAM_REASON_DONE |
- END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED |
- END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED);
+ END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
return 0;
}
if (options->ClientDNSRejectInternalAddresses) {
@@ -2805,8 +2806,12 @@
addr = ntohl(in.s_addr);
r = compare_addr_to_addr_policy(addr, conn->socks_request->port,
exit->exit_policy);
- if (r == ADDR_POLICY_REJECTED || r == ADDR_POLICY_PROBABLY_REJECTED)
- return 0;
+ if (r == ADDR_POLICY_REJECTED)
+ return 0; /* We know the address, and the exit policy rejects it. */
+ if (r == ADDR_POLICY_PROBABLY_REJECTED && !conn->chosen_exit_name)
+ return 0; /* We don't know the addr, but the exit policy rejects most
+ * addresses with this port. Since the user didn't ask for
+ * this node, err on the side of caution. */
} else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) {
/* Can't support reverse lookups without eventdns. */
if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR &&
diff -Nur tor-0.2.0.31/src/or/connection_or.c tor-0.2.0.32/src/or/connection_or.c
--- tor-0.2.0.31/src/or/connection_or.c 2008-06-13 07:12:28.000000000 +0200
+++ tor-0.2.0.32/src/or/connection_or.c 2008-11-20 23:14:25.000000000 +0100
@@ -157,7 +157,7 @@
void
var_cell_pack_header(const var_cell_t *cell, char *hdr_out)
{
- *(uint16_t*)(hdr_out) = htons(cell->circ_id);
+ set_uint16(hdr_out, htons(cell->circ_id));
*(uint8_t*)(hdr_out+2) = cell->command;
set_uint16(hdr_out+3, htons(cell->payload_len));
}
diff -Nur tor-0.2.0.31/src/or/directory.c tor-0.2.0.32/src/or/directory.c
--- tor-0.2.0.31/src/or/directory.c 2008-05-28 22:36:39.000000000 +0200
+++ tor-0.2.0.32/src/or/directory.c 2008-11-20 23:14:26.000000000 +0100
@@ -454,7 +454,12 @@
char address_buf[INET_NTOA_BUF_LEN+1];
struct in_addr in;
const char *address;
- if ((router = router_get_by_digest(status->identity_digest))) {
+ router = router_get_by_digest(status->identity_digest);
+ if (!router && anonymized_connection) {
+ log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
+ "don't have its router descriptor.", status->nickname);
+ return;
+ } else if (router) {
address = router->address;
} else {
in.s_addr = htonl(status->addr);
@@ -1805,7 +1810,7 @@
} else {
/* success. notify pending connections about this. */
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_here(conn->rend_query);
+ rend_client_desc_trynow(conn->rend_query, -1);
}
break;
case 404:
@@ -1851,7 +1856,7 @@
log_info(LD_REND, "Successfully fetched v2 rendezvous "
"descriptor.");
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_here(conn->rend_query);
+ rend_client_desc_trynow(conn->rend_query, -1);
break;
}
break;
@@ -2806,7 +2811,7 @@
* receive anything. */
write_http_status_line(conn, 400, "Nonauthoritative directory does not "
"accept posted server descriptors");
- return 0;
+ goto done;
}
if (authdir_mode_handles_descs(options, -1) &&
diff -Nur tor-0.2.0.31/src/or/dirvote.c tor-0.2.0.32/src/or/dirvote.c
--- tor-0.2.0.31/src/or/dirvote.c 2008-05-13 00:56:45.000000000 +0200
+++ tor-0.2.0.32/src/or/dirvote.c 2008-11-12 11:47:37.000000000 +0100
@@ -1089,8 +1089,8 @@
memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
DIGEST_LEN);
target_voter->signature_len = src_voter->signature_len;
- target_voter->good_signature = 1;
- target_voter->bad_signature = 0;
+ target_voter->good_signature = src_voter->good_signature;
+ target_voter->bad_signature = src_voter->bad_signature;
} else {
log_info(LD_DIR, "Not adding signature from %s", voter_identity);
}
@@ -1872,12 +1872,17 @@
sigs, msg_out);
log_info(LD_DIR,"Added %d signatures to consensus.", r);
- if (r >= 0) {
+ if (r >= 1) {
char *new_detached =
networkstatus_get_detached_signatures(pending_consensus);
const char *src;
char *dst, *dst_end;
- size_t new_consensus_len =
+ size_t new_consensus_len;
+ if (!new_detached) {
+ *msg_out = "No signatures to add";
+ goto err;
+ }
+ new_consensus_len =
strlen(pending_consensus_body) + strlen(new_detached) + 1;
pending_consensus_body = tor_realloc(pending_consensus_body,
new_consensus_len);
diff -Nur tor-0.2.0.31/src/or/main.c tor-0.2.0.32/src/or/main.c
--- tor-0.2.0.31/src/or/main.c 2008-06-13 06:18:28.000000000 +0200
+++ tor-0.2.0.32/src/or/main.c 2008-11-20 23:14:26.000000000 +0100
@@ -1113,8 +1113,10 @@
circuit_close_all_marked();
/** 7. And upload service descriptors if necessary. */
- if (has_completed_circuit && !we_are_hibernating())
+ if (has_completed_circuit && !we_are_hibernating()) {
rend_consider_services_upload(now);
+ rend_consider_descriptor_republication();
+ }
/** 8. and blow away any connections that need to die. have to do this now,
* because if we marked a conn for close and left its socket -1, then
diff -Nur tor-0.2.0.31/src/or/micro-revision.i tor-0.2.0.32/src/or/micro-revision.i
diff -Nur tor-0.2.0.31/src/or/or.h tor-0.2.0.32/src/or/or.h
--- tor-0.2.0.31/src/or/or.h 2008-09-02 00:06:47.000000000 +0200
+++ tor-0.2.0.32/src/or/or.h 2008-11-20 23:14:26.000000000 +0100
@@ -3645,7 +3645,7 @@
size_t request_len);
int rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
size_t request_len);
-void rend_client_desc_here(const char *query);
+void rend_client_desc_trynow(const char *query, int rend_version);
extend_info_t *rend_client_get_random_intro(const char *query);
@@ -3677,6 +3677,13 @@
/** List of the service's introduction points. Elements are removed if
* introduction attempts fail. */
smartlist_t *intro_nodes;
+ /** Has descriptor been uploaded to all hidden service directories? */
+ int all_uploads_performed;
+ /** List of hidden service directories to which an upload request for
+ * this descriptor could be sent. Smartlist exists only when at least one
+ * of the previous upload requests failed (otherwise it's not important
+ * to know which uploads succeeded and which not). */
+ smartlist_t *successful_uploads;
} rend_service_descriptor_t;
int rend_cmp_service_ids(const char *one, const char *two);
@@ -3738,6 +3745,8 @@
void rend_services_init(void);
void rend_services_introduce(void);
void rend_consider_services_upload(time_t now);
+void rend_hsdir_routers_changed(void);
+void rend_consider_descriptor_republication(void);
void rend_service_intro_has_opened(origin_circuit_t *circuit);
int rend_service_intro_established(origin_circuit_t *circuit,
diff -Nur tor-0.2.0.31/src/or/relay.c tor-0.2.0.32/src/or/relay.c
--- tor-0.2.0.31/src/or/relay.c 2008-06-13 07:12:28.000000000 +0200
+++ tor-0.2.0.32/src/or/relay.c 2008-11-20 23:21:32.000000000 +0100
@@ -751,8 +751,11 @@
ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+5));
else
ttl = -1;
- client_dns_set_addressmap(conn->socks_request->address, addr,
- conn->chosen_exit_name, ttl);
+
+ if (!(get_options()->ClientDNSRejectInternalAddresses &&
+ is_internal_IP(addr, 0)))
+ client_dns_set_addressmap(conn->socks_request->address, addr,
+ conn->chosen_exit_name, ttl);
}
/* check if he *ought* to have allowed it */
if (exitrouter &&
diff -Nur tor-0.2.0.31/src/or/rendclient.c tor-0.2.0.32/src/or/rendclient.c
--- tor-0.2.0.31/src/or/rendclient.c 2008-09-02 00:53:16.000000000 +0200
+++ tor-0.2.0.32/src/or/rendclient.c 2008-11-20 23:14:26.000000000 +0100
@@ -354,12 +354,13 @@
desc_id, DIGEST_LEN);
/* Only select those hidden service directories to which we did not send
- * a request recently. */
+ * a request recently and for which we have a router descriptor here. */
directory_clean_last_hid_serv_requests(); /* Clean request history first. */
SMARTLIST_FOREACH(responsible_dirs, routerstatus_t *, dir, {
if (lookup_last_hid_serv_request(dir, desc_id_base32, 0, 0) +
- REND_HID_SERV_DIR_REQUERY_PERIOD >= now)
+ REND_HID_SERV_DIR_REQUERY_PERIOD >= now ||
+ !router_get_by_digest(dir->identity_digest))
SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
});
@@ -461,6 +462,8 @@
log_info(LD_REND, "Could not pick one of the responsible hidden "
"service directories to fetch descriptors, because "
"we already tried them all unsuccessfully.");
+ /* Close pending connections (unless a v0 request is still going on). */
+ rend_client_desc_trynow(query, 2);
return;
}
@@ -617,11 +620,14 @@
/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
* are waiting on query. If there's a working cache entry here
- * with at least one intro point, move them to the next state;
- * else fail them.
+ * with at least one intro point, move them to the next state. If
+ * <b>rend_version</b> is non-negative, fail connections that have
+ * requested <b>query</b> unless there are still descriptor fetch
+ * requests in progress for other descriptor versions than
+ * <b>rend_version</b>.
*/
void
-rend_client_desc_here(const char *query)
+rend_client_desc_trynow(const char *query, int rend_version)
{
edge_connection_t *conn;
rend_cache_entry_t *entry;
@@ -657,9 +663,15 @@
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
}
} else { /* 404, or fetch didn't get that far */
- log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
- "unavailable (try again later).", safe_str(query));
- connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
+ /* Unless there are requests for another descriptor version pending,
+ * close the connection. */
+ if (rend_version >= 0 &&
+ !connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query,
+ rend_version == 0 ? 2 : 0)) {
+ log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
+ "unavailable (try again later).", safe_str(query));
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
+ }
}
});
}
diff -Nur tor-0.2.0.31/src/or/rendcommon.c tor-0.2.0.32/src/or/rendcommon.c
--- tor-0.2.0.31/src/or/rendcommon.c 2008-02-26 20:56:28.000000000 +0100
+++ tor-0.2.0.32/src/or/rendcommon.c 2008-11-20 23:14:26.000000000 +0100
@@ -32,6 +32,10 @@
rend_intro_point_free(intro););
smartlist_free(desc->intro_nodes);
}
+ if (desc->successful_uploads) {
+ SMARTLIST_FOREACH(desc->successful_uploads, char *, c, tor_free(c););
+ smartlist_free(desc->successful_uploads);
+ }
tor_free(desc);
}
@@ -884,6 +888,7 @@
if (!published && strmap_get_lc(rend_cache, key)) {
log_info(LD_REND, "We already have a v2 descriptor for service %s.",
safe_str(query));
+ rend_service_descriptor_free(parsed);
return -1;
}
/* report novel publication to statistics */
diff -Nur tor-0.2.0.31/src/or/rendservice.c tor-0.2.0.32/src/or/rendservice.c
--- tor-0.2.0.31/src/or/rendservice.c 2008-06-28 06:19:17.000000000 +0200
+++ tor-0.2.0.32/src/or/rendservice.c 2008-11-20 23:14:25.000000000 +0100
@@ -1066,11 +1066,13 @@
* <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
* purposes. */
static void
-directory_post_to_hs_dir(smartlist_t *descs, const char *service_id,
+directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
+ smartlist_t *descs, const char *service_id,
int seconds_valid)
{
- int i, j;
+ int i, j, failed_upload = 0;
smartlist_t *responsible_dirs = smartlist_create();
+ smartlist_t *successful_uploads = smartlist_create();
routerstatus_t *hs_dir;
for (i = 0; i < smartlist_len(descs); i++) {
rend_encoded_v2_service_descriptor_t *desc = smartlist_get(descs, i);
@@ -1080,11 +1082,24 @@
log_warn(LD_REND, "Could not determine the responsible hidden service "
"directories to post descriptors to.");
smartlist_free(responsible_dirs);
+ smartlist_free(successful_uploads);
return;
}
for (j = 0; j < smartlist_len(responsible_dirs); j++) {
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
hs_dir = smartlist_get(responsible_dirs, j);
+ if (smartlist_digest_isin(renddesc->successful_uploads,
+ hs_dir->identity_digest))
+ /* Don't upload descriptor if we succeeded in doing so last time. */
+ continue;
+ if (!router_get_by_digest(hs_dir->identity_digest)) {
+ log_info(LD_REND, "Not sending publish request for v2 descriptor to "
+ "hidden service directory '%s'; we don't have its "
+ "router descriptor. Queueing for later upload.",
+ hs_dir->nickname);
+ failed_upload = -1;
+ continue;
+ }
/* Send publish request. */
directory_initiate_command_routerstatus(hs_dir,
DIR_PURPOSE_UPLOAD_RENDDESC_V2,
@@ -1102,10 +1117,33 @@
seconds_valid,
hs_dir->nickname,
hs_dir->dir_port);
+ /* Remember successful upload to this router for next time. */
+ if (!smartlist_digest_isin(successful_uploads, hs_dir->identity_digest))
+ smartlist_add(successful_uploads, hs_dir->identity_digest);
}
smartlist_clear(responsible_dirs);
}
+ if (!failed_upload) {
+ if (renddesc->successful_uploads) {
+ SMARTLIST_FOREACH(renddesc->successful_uploads, char *, c, tor_free(c););
+ smartlist_free(renddesc->successful_uploads);
+ }
+ renddesc->all_uploads_performed = 1;
+ } else {
+ /* Remember which routers worked this time, so that we don't upload the
+ * descriptor to them again. */
+ if (!renddesc->successful_uploads)
+ renddesc->successful_uploads = smartlist_create();
+ SMARTLIST_FOREACH(successful_uploads, char *, c, {
+ if (!smartlist_digest_isin(renddesc->successful_uploads, c)) {
+ char *hsdir_id = tor_malloc_zero(DIGEST_LEN);
+ memcpy(hsdir_id, c, DIGEST_LEN);
+ smartlist_add(renddesc->successful_uploads, hsdir_id);
+ }
+ });
+ }
smartlist_free(responsible_dirs);
+ smartlist_free(successful_uploads);
}
/** Encode and sign up-to-date v0 and/or v2 service descriptors for
@@ -1120,9 +1158,6 @@
char serviceid[REND_SERVICE_ID_LEN_BASE32+1];
int uploaded = 0;
- /* Update the descriptor. */
- rend_service_update_descriptor(service);
-
rendpostperiod = get_options()->RendPostPeriod;
/* Upload unversioned (v0) descriptor? */
@@ -1172,7 +1207,8 @@
rend_get_service_id(service->desc->pk, serviceid);
log_info(LD_REND, "Sending publish request for hidden service %s",
serviceid);
- directory_post_to_hs_dir(descs, serviceid, seconds_valid);
+ directory_post_to_hs_dir(service->desc, descs, serviceid,
+ seconds_valid);
/* Free memory for descriptors. */
for (i = 0; i < smartlist_len(descs); i++)
rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
@@ -1196,7 +1232,8 @@
smartlist_free(descs);
return;
}
- directory_post_to_hs_dir(descs, serviceid, seconds_valid);
+ directory_post_to_hs_dir(service->desc, descs, serviceid,
+ seconds_valid);
/* Free memory for descriptors. */
for (i = 0; i < smartlist_len(descs); i++)
rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
@@ -1360,6 +1397,48 @@
/* if it's time, or if the directory servers have a wrong service
* descriptor and ours has been stable for 30 seconds, upload a
* new one of each format. */
+ rend_service_update_descriptor(service);
+ upload_service_descriptor(service);
+ }
+ }
+}
+
+/** True if the list of available router descriptors might have changed so
+ * that we should have a look whether we can republish previously failed
+ * rendezvous service descriptors. */
+static int consider_republishing_rend_descriptors = 1;
+
+/** Called when our internal view of the directory has changed, so that we
+ * might have router descriptors of hidden service directories available that
+ * we did not have before. */
+void
+rend_hsdir_routers_changed(void)
+{
+ consider_republishing_rend_descriptors = 1;
+}
+
+/** Consider republication of v2 rendezvous service descriptors that failed
+ * previously, but without regenerating descriptor contents.
+ */
+void
+rend_consider_descriptor_republication(void)
+{
+ int i;
+ rend_service_t *service;
+
+ if (!consider_republishing_rend_descriptors)
+ return;
+ consider_republishing_rend_descriptors = 0;
+
+ if (!get_options()->PublishHidServDescriptors)
+ return;
+
+ for (i=0; i < smartlist_len(rend_service_list); ++i) {
+ service = smartlist_get(rend_service_list, i);
+ if (service->descriptor_version && service->desc &&
+ !service->desc->all_uploads_performed) {
+ /* If we failed in uploading a descriptor last time, try again *without*
+ * updating the descriptor's contents. */
upload_service_descriptor(service);
}
}
diff -Nur tor-0.2.0.31/src/or/routerlist.c tor-0.2.0.32/src/or/routerlist.c
--- tor-0.2.0.31/src/or/routerlist.c 2008-06-19 06:59:43.000000000 +0200
+++ tor-0.2.0.32/src/or/routerlist.c 2008-11-20 23:14:25.000000000 +0100
@@ -4116,6 +4116,7 @@
router_dir_info_changed(void)
{
need_to_update_have_min_dir_info = 1;
+ rend_hsdir_routers_changed();
}
/** Return a string describing what we're missing before we have enough
diff -Nur tor-0.2.0.31/src/win32/orconfig.h tor-0.2.0.32/src/win32/orconfig.h
diff -Nur tor-0.2.0.31/tor.spec tor-0.2.0.32/tor.spec
[not relevant]
diff -u tor-0.2.0.31/debian/changelog tor-0.2.0.32/debian/changelog
--- tor-0.2.0.31/debian/changelog
+++ tor-0.2.0.32/debian/changelog
@@ -1,3 +1,12 @@
+tor (0.2.0.32-1) unstable; urgency=high
+
+ * New upstream version.
+ - Properly drops privileges when being configured to do
+ so (closes: #505178).
+ * No longer set now obsolete Group setting in built-in debian config.
+
+ -- Peter Palfrader <weasel@debian.org> Fri, 21 Nov 2008 23:33:15 +0100
+
tor (0.2.0.31-1) unstable; urgency=low
* New upstream version.
diff -u tor-0.2.0.31/debian/patches/06_add_compile_time_defaults.dpatch tor-0.2.0.32/debian/patches/06_add_compile_time_defaults.dpatch
--- tor-0.2.0.31/debian/patches/06_add_compile_time_defaults.dpatch
+++ tor-0.2.0.32/debian/patches/06_add_compile_time_defaults.dpatch
@@ -72,7 +72,7 @@
if (errmsg) {
log(LOG_WARN,LD_CONFIG,"Failed to parse/validate config: %s", errmsg);
tor_free(errmsg);
-@@ -5011,3 +5018,64 @@
+@@ -5011,3 +5018,60 @@
puts(routerparse_c_id);
}
@@ -132,8 +132,4 @@
+ var->initvalue = tor_strdup("debian-tor");
+
-+ var = config_find_option(&options_format, "Group");
-+ tor_assert(var);
-+ var->initvalue = tor_strdup("debian-tor");
-+
+ return 0;
+}
Reply to: