commit 52ffae96fbe3907644015be82de2b3a38f637ae2 Author: George Kadianakis desnacked@riseup.net Date: Fri May 9 15:32:55 2014 +0100
Write password to a file, instead of the whole Bridge line.
Because of technical problems (see #10887:comment:11) it was not so easy to write the actual Bridge line that people were supposed to use. Let's just write the password for now.
Conflicts: obfsproxy/transports/scramblesuit/const.py obfsproxy/transports/scramblesuit/state.py
Conflicts: obfsproxy/transports/scramblesuit/scramblesuit.py --- ChangeLog | 3 +++ obfsproxy/transports/scramblesuit/const.py | 4 ++++ obfsproxy/transports/scramblesuit/scramblesuit.py | 13 ++++++++++- obfsproxy/transports/scramblesuit/state.py | 26 +++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog index 93c47fd..b6a2ad4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ Changes in version 0.2.11 - UNRELEASED: + - Write a 'server_password' file with the scramblesuit password to + make it easier for bridge operators to find their password. Patch + by Philipp Winter. Fixes #10887. - Add --password-file switch for providing scramblesuit passwords. Patch by irregulator. Fixes #8040. - Fix bug to prevent denial-of-service attacks targeting the diff --git a/obfsproxy/transports/scramblesuit/const.py b/obfsproxy/transports/scramblesuit/const.py index 8addabc..df4b0af 100644 --- a/obfsproxy/transports/scramblesuit/const.py +++ b/obfsproxy/transports/scramblesuit/const.py @@ -18,6 +18,10 @@ TICKET_AES_CBC_IV_LENGTH = 16 # directory but is later set by `setStateLocation()' in util.py. STATE_LOCATION = ""
+# Contains a ready-to-use bridge descriptor (in managed mode) or simply the +# server's bind address together with the password (in external mode). +PASSWORD_FILE = "server_password" + # Divisor (in seconds) for the Unix epoch used to defend against replay # attacks. EPOCH_GRANULARITY = 3600 diff --git a/obfsproxy/transports/scramblesuit/scramblesuit.py b/obfsproxy/transports/scramblesuit/scramblesuit.py index 725c253..9f5daf5 100644 --- a/obfsproxy/transports/scramblesuit/scramblesuit.py +++ b/obfsproxy/transports/scramblesuit/scramblesuit.py @@ -133,7 +133,18 @@ class ScrambleSuitTransport( base.BaseTransport ): "'generate_password.py' to generate a good " \ "password." % cfg["password"])
- cls.uniformDHSecret = cls.uniformDHSecret.strip() + if cls.weAreServer: + if not hasattr(cls, "uniformDHSecret"): + log.debug("Using fallback password for descriptor file.") + srv = state.load() + cls.uniformDHSecret = srv.fallbackPassword + + if len(cls.uniformDHSecret) != const.SHARED_SECRET_LENGTH: + raise base.TransportSetupFailed( + "Wrong password length (%d instead of %d)" + % len(cls.uniformDHSecret), const.SHARED_SECRET_LENGTH) + + state.writeServerPassword(cls.uniformDHSecret)
@classmethod def get_public_server_options( cls, transportOptions ): diff --git a/obfsproxy/transports/scramblesuit/state.py b/obfsproxy/transports/scramblesuit/state.py index 5158f5e..ce6a5d1 100644 --- a/obfsproxy/transports/scramblesuit/state.py +++ b/obfsproxy/transports/scramblesuit/state.py @@ -17,6 +17,7 @@ import const import replay import mycrypto import probdist +import base64
import obfsproxy.common.log as logging
@@ -51,6 +52,31 @@ def load( ):
return stateObject
+def writeServerPassword( password ): + """ + Dump our ScrambleSuit server descriptor to file. + + The file should make it easy for bridge operators to obtain copy & + pasteable server descriptors. + """ + + assert len(password) == const.SHARED_SECRET_LENGTH + assert const.STATE_LOCATION != "" + + passwordFile = os.path.join(const.STATE_LOCATION, const.PASSWORD_FILE) + log.info("Writing server password to file `%s'." % passwordFile) + + password_str = "# You are supposed to give this password to your clients to append it to their Bridge line" + password_str = "# For example: Bridge scramblesuit 192.0.2.1:5555 EXAMPLEFINGERPRINTNOTREAL password=EXAMPLEPASSWORDNOTREAL" + password_str = "# Here is your password:" + password_str = "password=%s\n" % base64.b32encode(password) + try: + with open(passwordFile, 'w') as fd: + fd.write(password_str) + except IOError as err: + log.error("Error writing password file to `%s': %s" % + (passwordFile, err)) + class State( object ):
"""