Package Peach :: Package Agent :: Module socketmon
[hide private]

Source Code for Module Peach.Agent.socketmon

  1   
  2  # 
  3  # Copyright (c) 2008 Blake Frantz & Michael Eddington 
  4  # 
  5  # Permission is hereby granted, free of charge, to any person obtaining a copy  
  6  # of this software and associated documentation files (the "Software"), to deal 
  7  # in the Software without restriction, including without limitation the rights  
  8  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
  9  # copies of the Software, and to permit persons to whom the Software is  
 10  # furnished to do so, subject to the following conditions: 
 11  # 
 12  # The above copyright notice and this permission notice shall be included in     
 13  # all copies or substantial portions of the Software. 
 14  # 
 15  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 16  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 17  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 18  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 19  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 20  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 21  # SOFTWARE. 
 22  # 
 23  # Authors: 
 24  #  Blake Frantz (blakefrantz@gmail.com) 
 25  # 
 26  # Description: 
 27  #   Monitors a given socket and faults on a connection. This is useful when 
 28  #   fuzzing for cross site scripting issues. By embedding image tags that  
 29  #   point to this monitor we are able to determine when the browser has 
 30  #   rendered our injection attempt. 
 31  # 
 32  # $Id: socketmon.py 780 2008-03-23 02:58:49Z meddingt $ 
 33   
 34  #TODO: Port this over to use ThreadedSelectReactor  
 35  # see http://twistedmatrix.com/documents/current/api/twisted.internet._threadedselect.ThreadedSelectReactor.html 
 36   
 37  import sys, time, socket 
 38   
 39  sys.path.append("..") 
 40  sys.path.append("../..") 
 41   
 42  from Peach.agent import Monitor 
 43  from twisted.internet import reactor, protocol 
 44  from threading import Thread 
 45   
 46  g_socketData = None 
 47  g_faultDetected = False 
 48  g_stopReactor = False 
 49   
50 -class SocketMonitor(Monitor):
51
52 - def __init__(self, args):
53 ''' 54 Constructor. Arguments are supplied via the Peach XML 55 file. 56 57 @type args: Dictionary 58 @param args: Dictionary of parameters 59 ''' 60 61 try: 62 63 # Our name for this monitor 64 self._name = "Socket Monitor" 65 self._ip = "" 66 self._port = "" 67 self._protocol = "" 68 69 self._thread = None 70 71 self._internalError = False 72 self._stopOnFault = False 73 74 # Report an error if no MemoryLimit and/or neither pid nor processName is defined 75 76 while 1: 77 78 if args.has_key('IP'): 79 self._ip = str(args["IP"]) 80 else: 81 print "Socket Monitor: No IP specified, using using 127.0.0.1" 82 self._ip = "127.0.0.1" 83 84 if args.has_key('Port'): 85 self._port = int(args['Port']) 86 print "Socket Monitor: Listening on Port: %s" % self._port 87 else: 88 print "Socket Monitor: No Port specified, using 80" 89 self._port = "8002" 90 91 if args.has_key('Protocol'): 92 self._protocol = args['Protocol'] 93 print "Socket Monitor: Protocol = %s" % self._protocol 94 else: 95 print "Socket Monitor: No Protocol specified, using TCP" 96 self._protocol = "tcp" 97 break 98 99 except: 100 self._internalError = True 101 print "Socket Monitor: Caught Exception Parsing Arguments" 102 raise
103
104 - def OnTestStarting(self):
105 ''' 106 Called right before start of test case or variation 107 ''' 108 109 global g_faultDetected 110 global g_socketData 111 112 # fire up twisted if it hasn't been already 113 if self._thread == None: 114 self._thread = ReactorThread(self._ip, self._port, self._protocol) 115 self._thread.start() 116 117 g_socketData = None 118 g_faultDetected = False 119 120 return
121
122 - def OnTestFinished(self):
123 ''' 124 Called right after a test case or varation 125 ''' 126 pass
127
128 - def GetMonitorData(self):
129 ''' 130 Get any monitored data from a test case. 131 ''' 132 133 global g_socketData 134 return {'SocketData.txt': str(g_socketData)}
135
136 - def DetectedFault(self):
137 ''' 138 Check if a fault was detected. 139 ''' 140 global g_faultDetected 141 return g_faultDetected
142
143 - def OnFault(self):
144 ''' 145 Called when a fault was detected. 146 ''' 147 pass
148
149 - def OnShutdown(self):
150 ''' 151 Called when Agent is shutting down, typically at end 152 of a test run or when a Stop-Run occurs 153 ''' 154 global g_stopReactor 155 g_stopReactor = True 156 157 s = None 158 159 # hack to stop reactor 160 if(self._protocol.lower() == "tcp"): 161 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 162 else: 163 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 164 165 s.connect((self._ip, int(self._port))) 166 s.close()
167
168 - def StopRun(self):
169 ''' 170 Return True to force test run to fail. This 171 should return True if an unrecoverable error 172 occurs. 173 ''' 174 return self._internalError
175
176 -class ReactorThread(Thread):
177
178 - def __init__(self, ip, port, protocol):
179 Thread.__init__(self) 180 self._ip = ip 181 self._port = port 182 self._protocol = protocol 183 self._factory = None
184
185 - def run(self):
186 self._factory = protocol.ServerFactory() 187 self._factory.protocol = Listener 188 189 if self._protocol.lower() == "tcp": 190 reactor.listenTCP(int(self._port), self._factory) 191 else: 192 reactor.listenUDP(int(self._port), self._factory) 193 194 reactor.run(installSignalHandlers=0)
195
196 -class Listener(protocol.Protocol):
197
198 - def connectionMade(self):
199 200 global g_stopReactor 201 global g_socketData 202 203 # hack until ThreadedSelectReactor is implemented 204 if g_stopReactor == True: 205 print "Socket Monitor: Stopping Reactor" 206 reactor.stop() 207 else: 208 209 host = self.transport.getHost() 210 211 g_socketData = host.host + ":" + str(host.port) 212 213 global g_faultDetected 214 g_faultDetected = True
215 216 if __name__ == "__main__": 217 d = {} 218 d["IP"] = "127.0.0.1" 219 d["Port"] = "8002" 220 d["Protocol"] = "tcp" 221 222 a = SocketMonitor(d) 223 a.OnTestStarting() 224 225 while True: 226 a.OnTestStarting() 227 time.sleep(2) 228 print a.DetectedFault() 229 a.OnTestFinished() 230 231 a.OnShutdown() 232