[tor-commits] [flashproxy/master] Add helper daemon for indirect URL registration.

dcf at torproject.org dcf at torproject.org
Wed Mar 13 09:01:24 UTC 2013


commit ab8ecafb5d424b7c9ba720a3bc06e1b948555153
Author: Alexandre Allaire <alexandre.allaire at mail.mcgill.ca>
Date:   Thu Jan 17 20:34:26 2013 -0500

    Add helper daemon for indirect URL registration.
    
    Add a daemon which accepts RSA encrypted, base64 encoded
    client addresses and registers them with the facilitator.
    It is meant to be used by facilitator.cgi upon receiving
    a registration through a GET request.
---
 facilitator/facilitator-reg-url |  157 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/facilitator/facilitator-reg-url b/facilitator/facilitator-reg-url
new file mode 100644
index 0000000..0127719
--- /dev/null
+++ b/facilitator/facilitator-reg-url
@@ -0,0 +1,157 @@
+#!/usr/bin/python
+
+import sys
+import base64
+import getopt
+import traceback
+import socket
+import time
+import os
+
+from M2Crypto import RSA
+
+import fac
+
+DEFAULT_FACILITATOR_ADDR = ("127.0.0.1", 9002)
+DEFAULT_RSA_KEY_FILE = "/etc/flashproxy/reg-url.key"
+DEFAULT_PORT = 9003
+DEFAULT_LOG_FILE = "/var/log/facilitator-reg-url.log"
+
+LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
+
+# M2Crypto RSA object
+rsa = None
+
+class options(object):
+    log_filename = DEFAULT_LOG_FILE
+    log_file = sys.stdout
+    port = DEFAULT_PORT
+    debug = False
+    daemonize = True
+    key_file = DEFAULT_RSA_KEY_FILE
+    facilitator = DEFAULT_FACILITATOR_ADDR
+    safe_logging = True
+    pid_filename = None
+
+def usage():
+    print """
+Usage: %(progname)s
+
+Helper daemon for registration by indirect URL. Receives
+client addresses from facilitator.cgi, decrypts them and
+registers them with the facilitator.
+
+  -h, --help              print this help message and exit.
+  -d, --debug             don't daemonize, log to stdout.
+  -k, --key=KEYFILE       read the RSA private key from KEYFILE.
+  -f, --facilitator=ADDR  register with facilitator listening at ADDR.
+  -p, --port=PORT         listen for registrations on this port (default %(port)s).
+  -l, --log FILE          write log to FILE (default "%(log)s").
+      --pidfile FILE      write pid to file after daemonizing.
+      --unsafe-logging    don't scrub IP addresses from logs.
+""" % {
+    "progname": sys.argv[0],
+    "port": DEFAULT_PORT,
+    "log": DEFAULT_LOG_FILE,
+}
+
+def safe_str(s):
+    """Return s if options.safe_logging is true, and "[scrubbed]" otherwise."""
+    if options.safe_logging:
+        return "[scrubbed]"
+    else:
+        return s
+
+def log(msg):
+    print >> options.log_file, (u"%s %s" % (time.strftime(LOG_DATE_FORMAT), msg)).encode("UTF-8")
+    options.log_file.flush()
+
+def register(reg):
+    try:
+        ciphertext = base64.urlsafe_b64decode(reg)
+        client_spec = rsa.private_decrypt(ciphertext, RSA.pkcs1_oaep_padding)
+    except:
+        log(u"Error occurred while decoding and decrypting registration:")
+        traceback.print_exc(file=options.log_file)
+        return False
+    try:
+        client_addr = fac.parse_addr_spec(client_spec)
+    except ValueError:
+        log(u"Registration of %s failed because of parsing error:" % safe_str(client_spec))
+        traceback.print_exc(file=options.log_file)
+        return False
+    if not fac.put_reg(options.facilitator, client_addr):
+        log(u"Regstration of %s failed at the facilitator." % safe_str(client_spec))
+        return False
+    log(u"Registered %s" % safe_str(client_spec))
+    return True
+
+def loop():
+    sock = socket.socket()
+    sock.bind(('', options.port))
+    sock.listen(5)
+
+    while True:
+        client, _ = sock.accept()
+        reg, buf = "", ""
+        while True:
+            buf = client.recv(4096)
+            if buf == "":
+                break
+            reg += buf
+        if register(reg):
+            client.send("\x00")
+        else:
+            client.send("\x01")
+        client.shutdown(socket.SHUT_RDWR)
+        client.close()
+
+def main():
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "hdl:p:k:f:", ["help", "debug", "log=", "port=", "key=", "facilitator=", "pidfile=", "unsafe-logging"])
+    for o, a in opts:
+        if o == "-h" or o == "--help":
+            usage()
+            sys.exit(0)
+        if o == "-d" or o == "--debug":
+            options.daemonize = False
+            options.log_filename = False
+        if o == "-l" or o == "--log":
+            options.log_filename = a
+        if o == "-p" or o == "--port":
+            options.port = int(a)
+        if o == "-k" or o == "--key":
+            options.key_file = a
+        if o == "-f" or o == "--facilitator":
+            options.facilitator = fac.parse_addr_spec(a, resolve=True)
+        if o == "--pidfile":
+            options.pid_filename = a
+        if o == "--unsafe-logging":
+            options.safe_logging = False
+
+    if options.daemonize:
+        log(u"daemonizing")
+        pid = os.fork()
+        if pid != 0:
+            if options.pid_filename:
+                f = open(options.pid_filename, "w")
+                print >> f, pid
+                f.close()
+            sys.exit(0)
+
+    if options.log_filename:
+        options.log_file = open(options.log_filename, "a")
+    log(u"Starting on port %s" % options.port)
+
+    # Load RSA key.
+    try:
+        global rsa
+        rsa = RSA.load_key(options.key_file)
+    except:
+        log(u"Failed to load RSA private key:")
+        traceback.print_exc(file=options.log_file)
+        sys.exit(1)
+
+    loop()
+
+if __name__ == "__main__":
+    main()





More information about the tor-commits mailing list