commit ab8ecafb5d424b7c9ba720a3bc06e1b948555153 Author: Alexandre Allaire alexandre.allaire@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()