[tor-commits] [flashproxy/master] Add daemon options to facilitator-email-poller.

dcf at torproject.org dcf at torproject.org
Fri Sep 28 06:11:19 UTC 2012


commit eac7da3fc2ec852966a582bd48f8018df4f2a340
Author: David Fifield <david at bamsoftware.com>
Date:   Wed Sep 19 16:50:27 2012 -0700

    Add daemon options to facilitator-email-poller.
---
 facilitator/facilitator-email-poller |   72 ++++++++++++++++++++++++++++++---
 1 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/facilitator/facilitator-email-poller b/facilitator/facilitator-email-poller
index c9d9a84..42bf2dc 100755
--- a/facilitator/facilitator-email-poller
+++ b/facilitator/facilitator-email-poller
@@ -19,6 +19,7 @@ from M2Crypto import BIO, RSA, X509
 DEFAULT_IMAP_HOST = "imap.gmail.com"
 DEFAULT_IMAP_PORT = 993
 DEFAULT_EMAIL_ADDRESS = "hoddwee at gmail.com"
+DEFAULT_LOG_FILENAME = "facilitator-email-poller.log"
 
 POLL_INTERVAL = 60
 
@@ -57,12 +58,19 @@ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
 # hashing the public key, not the entire certificate.
 PUBKEY_SHA1 = "5d97e1ec007e48c1f36e736e652eeaf2184697c3".decode("hex")
 
+LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
+
 class options(object):
     email_addr = None
     imap_addr = None
     key_filename = None
     password_filename = None
-    debug = False
+    log_filename = DEFAULT_LOG_FILENAME
+    log_file = sys.stdout
+    daemonize = True
+    pid_filename = None
+    safe_logging = True
+    imaplib_debug = False
 
 def usage(f = sys.stdout):
     print >> f, """\
@@ -71,26 +79,42 @@ Facilitator-side helper for the facilitator-reg-email rendezvous. Polls
 an IMAP server for email messages with client registrations, deletes
 them, and forwards the registrations to the facilitator.
 
-  -d, --debug             enable debugging output (Python imaplib messages);
-                            beware that the login password will be shown.
+  -d, --debug             don't daemonize, log to stdout.
   -e, --email=ADDRESS     log in as ADDRESS (default "%(email_addr)s").
   -h, --help              show this help.
   -i, --imap=HOST[:PORT]  use the given IMAP server (default "%(imap_addr)s").
+      --imaplib-debug     show raw IMAP messages.
   -k, --key=KEYFILE       read a facilitator private key from KEYFILE.
-  -p, --pass=PASSFILE     use the email password contained in PASSFILE.\
+  -l, --log FILENAME      write log to FILENAME (default \"%(log)s\").
+  -p, --pass=PASSFILE     use the email password contained in PASSFILE.
+      --pidfile FILENAME  write PID to FILENAME after daemonizing.
+      --unsafe-logging    don't scrub email password and IP addresses from logs.\
 """ % {
     "progname": sys.argv[0],
     "email_addr": DEFAULT_EMAIL_ADDRESS,
     "imap_addr": fac.format_addr((DEFAULT_IMAP_HOST, DEFAULT_IMAP_PORT)),
+    "log": DEFAULT_LOG_FILENAME,
 }
 
+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()
+
 options.email_addr = DEFAULT_EMAIL_ADDRESS
 options.imap_addr = (DEFAULT_IMAP_HOST, DEFAULT_IMAP_PORT)
 
-opts, args = getopt.gnu_getopt(sys.argv[1:], "de:hi:k:p:", ["debug", "email=", "help", "imap=", "key=", "pass="])
+opts, args = getopt.gnu_getopt(sys.argv[1:], "de:hi:k:l:p:", ["debug", "email=", "help", "imap=", "imaplib-debug", "key=", "log=", "pass=", "pidfile=", "unsafe-logging"])
 for o, a in opts:
     if o == "-d" or o == "--debug":
-        options.debug = True
+        options.daemonize = False
+        options.log_filename = None
     elif o == "-e" or o == "--email":
         options.email_addr = a
     elif o == "-h" or o == "--help":
@@ -98,10 +122,18 @@ for o, a in opts:
         sys.exit()
     elif o == "-i" or o == "--imap":
         options.imap_addr = fac.parse_addr_spec(a, DEFAULT_IMAP_HOST, DEFAULT_IMAP_PORT)
+    if o == "--imaplib-debug":
+        options.imaplib_debug = True
     elif o == "-k" or o == "--key":
         options.key_filename = a
+    elif o == "-l" or o == "--log":
+        options.log_filename = a
     elif o == "-p" or o == "--pass":
         options.password_filename = a
+    elif o == "--pidfile":
+        options.pid_filename = a
+    elif o == "--unsafe-logging":
+        options.safe_logging = False
 
 if len(args) != 0:
     usage(sys.stderr)
@@ -179,6 +211,7 @@ def handle_message(msg):
     ciphertext = msg.get_payload().decode("base64")
     plaintext = rsa.private_decrypt(ciphertext, RSA.pkcs1_oaep_padding)
     client_addr = find_client_addr(plaintext)
+    log(u"registering %s" % safe_str(fac.format_addr(client_addr)))
     fac.put_reg(FACILITATOR_ADDR, client_addr)
 
 def imap_loop(imap):
@@ -204,7 +237,24 @@ def imap_loop(imap):
 
         time.sleep(POLL_INTERVAL)
 
-if options.debug:
+if options.log_filename:
+    options.log_file = open(options.log_filename, "a")
+    # Send error tracebacks to the log.
+    sys.stderr = options.log_file
+else:
+    options.log_file = sys.stdout
+
+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.imaplib_debug:
     imaplib.Debug = 4
 
 ca_certs_file = tempfile.NamedTemporaryFile(prefix="facilitator-email-poller-", suffix=".crt", delete=True)
@@ -226,9 +276,17 @@ if pubkey_digest != PUBKEY_SHA1:
     raise ValueError("Public key does not match pin: got %s but expected %s" %
         (pubkey_digest.encode("hex"), PUBKEY_SHA1.encode("hex")))
 
+pre_debug = imap.debug
+if options.safe_logging:
+    # Don't log the login call without --unsafe-logging because it contains a
+    # secret password.
+    imap.debug = 0
+log(u"logging in as %s" % options.email_addr)
 imap.login(options.email_addr, email_password)
+imap.debug = pre_debug
 
 imap_loop(imap)
 
+log(u"closing")
 imap.close()
 imap.logout()





More information about the tor-commits mailing list