gettor.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/python2.5
  2. # -*- coding: utf-8 -*-
  3. """
  4. gettor.py by Jacob Appelbaum <jacob@appelbaum.net>
  5. This program will hand out Tor via email to supported systems.
  6. This program is Free Software released under the GPLv3.
  7. It is intended to be used in a .forward file as part of a pipe like so:
  8. cat <<'EOF'> .forward
  9. |/usr/local/bin/gettor.py
  10. EOF
  11. You should have a dist/current/ mirror in a directory that gettor can read.
  12. Such a mirror can be created like so:
  13. cd /usr/local/
  14. rsync -av rsync://rsync.torproject.org/tor/dist/current tor-dist-current/
  15. You can keep it updated with a cronjob like so:
  16. MirrorDir=/usr/local/tor-dist-current/
  17. 0 3 * * * rsync -a rsync://rsync.torproject.org/tor/dist/current/ $MirrorDir
  18. You should ensure that for each file and signature pair you wish to
  19. distribute, you have created a zip file containing both.
  20. While this program isn't written in a threaded manner per se, it is designed to function
  21. as if it will be called as a pipe many times at once. There is a slight
  22. desynchronization with blacklist entry checking and may result in false
  23. negatives. This isn't perfect but it is designed to be lightweight. It could
  24. be fixed easily with a shared locking system but this isn't implemented yet.
  25. """
  26. __program__ = 'gettor.py'
  27. __version__ = '20080713.00'
  28. __url__ = 'https://tor-svn.freehaven.net/svn/tor/trunk/contrib/gettor/'
  29. __author__ = 'Jacob Appelbaum <jacob@appelbaum.net>'
  30. __copyright__ = 'Copyright (c) 2008, Jacob Appelbaum'
  31. __license__ = 'See LICENSE for licensing information'
  32. try:
  33. from future import antigravity
  34. except ImportError:
  35. antigravity = None
  36. import syslog
  37. import gettor_blacklist
  38. import gettor_requests
  39. import gettor_responses
  40. if __name__ == "__main__":
  41. rawMessage = gettor_requests.getMessage()
  42. parsedMessage = gettor_requests.parseMessage(rawMessage)
  43. if not parsedMessage:
  44. syslog.syslog("gettor: No parsed message. Dropping message.")
  45. print "gettor: No parsed message. Dropping message."
  46. exit(1)
  47. signature = False
  48. signature = gettor_requests.verifySignature(rawMessage)
  49. print "Signature is : " + str(signature)
  50. replyTo = False
  51. srcEmail = "gettor@torproject.org"
  52. # TODO XXX:
  53. # Make the zip files and ensure they match packageList
  54. # Make each zip file like so:
  55. # zip -9 windows-bindle.z \
  56. # vidalia-bundle-0.2.0.29-rc-0.1.6.exe \
  57. # vidalia-bundle-0.2.0.29-rc-0.1.6.exe.asc
  58. #
  59. packageList = {
  60. "windows-bundle": "/tmp/windows-bundle.z",
  61. "macosx-bundle": "/tmp/macosx-bundle.z",
  62. "linux-bundle": "/tmp/linux-bundle.z",
  63. "source-bundle": "/tmp/source-bundle.z"
  64. }
  65. # XXX TODO: Ensure we have a proper replyTO or bail out (majorly malformed mail).
  66. replyTo = gettor_requests.parseReply(parsedMessage)
  67. if not signature:
  68. # Check to see if we've helped them to understand that they need DKIM in the past
  69. previouslyHelped = gettor_blacklist.blackList(replyTo)
  70. if not replyTo:
  71. syslog.syslog("No help dispatched. Invalid reply address for user.")
  72. print "No help dispatched. Invalid reply address for user."
  73. exit(1)
  74. if not signature and previouslyHelped:
  75. syslog.syslog("gettor: Unsigned messaged to gettor by blacklisted user dropped.")
  76. print "No help dispatched. Unsigned and unhelped for blacklisted user."
  77. exit(1)
  78. if not signature and not previouslyHelped:
  79. # Reply with some help and bail out
  80. # Someday call blackList(replyTo)
  81. message = """
  82. You should try your request again with a provider that implements DKIM. Sorry.
  83. """
  84. gettor_responses.sendHelp(message, srcEmail, replyTo)
  85. print "attempting to send email from: " + srcEmail + "The mail is sent to: " + replyTo
  86. syslog.syslog("gettor: Unsigned messaged to gettor. We issued some help about using DKIM.")
  87. print "gettor: Unsigned messaged to gettor. We issued some help about using DKIM."
  88. exit(0)
  89. if signature:
  90. syslog.syslog("gettor: Signed messaged to gettor.")
  91. print "gettor: Signed messaged to gettor."
  92. try:
  93. print "gettor: Parsing now."
  94. package = gettor_requests.parseRequest(parsedMessage, packageList)
  95. except:
  96. package = None
  97. if package == "windows-bundle":
  98. print "gettor: " + package + " selected."
  99. syslog.syslog("gettor: " + package + " selected.")
  100. message = "Here's your requested software as a zip file. Please \
  101. verify the signature."
  102. print "attempting to send email from: " +
  103. srcEmail + "The mail is sent to: " + replyTo
  104. gettor_responses.sendPackage(message, srcEmail, replyTo, packageList[package])
  105. exit(0)
  106. else:
  107. print "Package request is unknown: " + package
  108. message = " Your request was misunderstood. Please select one of the \
  109. following packages: " + packageList.keys()
  110. gettor_responses.sendHelp(message, srcEmail, replyTo)
  111. print "attempting to send email from: " + srcEmail + "The mail is sent to: " + replyTo
  112. syslog.syslog("gettor: Signed messaged to gettor. We issued some help about proper email formatting.")
  113. print "gettor: Signed messaged to gettor. We issued some help about proper email formatting."
  114. exit(0)