def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # event, overlapped struct for the pipe or tunnel hEvent_pipe = win32event.CreateEvent(None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe # buffer for the packets message_readfile = win32file.AllocateReadBuffer(4096) # showing if we already async reading or not not_reading_already = True first_run = True while not self._stop: try: if not self.tunnel_r: # user is not authenticated yet, so there is no pipe # only checking the socket for data rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: # client mode so we have the socket and tunnel as well # or the client authenticated and the pipe was created if first_run or not_reading_already: # no ReadFile was called before or finished, so we # are calling it again hr, _ = win32file.ReadFile(self.tunnel_r, message_readfile, overlapped_pipe) not_reading_already = first_run = False if (hr == winerror.ERROR_IO_PENDING): # well, this was an async read, so we need to wait # until it happens rc = win32event.WaitForMultipleObjects( [hEvent_sock, hEvent_pipe], 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if hr != 0: common.internal_print( "{0} ReadFile failed: {1}".format( self.module_short, hr), -1) raise if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc == 0: # socket got signalled not_reading_already = False messages = self.recv() for message in messages: # looping through the messages from socket if len(message) == 0: # this could happen when the socket died or # partial message was read. continue if common.is_control_channel(message[0:1]): # parse control messages if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE ):], None): continue else: self.stop() break if self.authenticated: try: # write packet to the tunnel self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE ):]) except OSError as e: print(e) # wut? except Exception as e: if e.args[0] == 995: common.internal_print( "Interface disappered, exiting thread: {0}" .format(e), -1) self.stop() continue if rc == 1: # pipe/tunnel got signalled not_reading_already = True if (overlapped_pipe.InternalHigh < 4) or (message_readfile[0:1] != "\x45"): #Only care about IPv4 # too small which should not happen or not IPv4, so we just drop it. continue # reading out the packet from the buffer and discarding the rest readytogo = message_readfile[0:overlapped_pipe. InternalHigh] self.send(common.DATA_CHANNEL_BYTE, readytogo, None) except win32api.error as e: common.internal_print("TCP Exception: {0}".format(e), -1) self.cleanup() return True
def communication_unix(self, is_check): rlist = [self.comms_socket] wlist = [] xlist = [] while not self._stop: if self.tunnel_r: rlist = [self.tunnel_r, self.comms_socket] try: readable, writable, exceptional = select.select( rlist, wlist, xlist, self.timeout) except select.error, e: break if self._stop: self.comms_socket.close() break try: for s in readable: if (s is self.tunnel_r) and not self._stop: message = self.packet_reader(self.tunnel_r, True, self.serverorclient) while True: if (len(message) < 4) or (message[0:1] != "\x45" ): #Only care about IPv4 break packetlen = struct.unpack( ">H", message[2:4])[0] # IP Total length if packetlen > len(message): message += self.packet_reader( self.tunnel_r, False, self.serverorclient) readytogo = message[0:packetlen] message = message[packetlen:] self.send(common.DATA_CHANNEL_BYTE, readytogo, None) if (s is self.comms_socket) and not self._stop: messages = self.recv() for message in messages: if len(message) == 0: continue if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE ):], None): continue else: self.stop() break if self.authenticated: try: self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE ):]) except OSError as e: print(e) # wut? except Exception as e: print(e) except (socket.error, OSError, IOError): if self.serverorclient: common.internal_print("Client lost. Closing down thread.", -1) self.cleanup() return if not self.serverorclient: common.internal_print("Server lost. Closing connection.", -1) self.comms_socket.close() break except: print("another error") raise
def communication_unix(self, is_check): sequence = 0 identifier = 0 self.rlist = [self.comms_socket] if not self.serverorclient and self.tunnel: self.rlist = [self.tunnel, self.comms_socket] wlist = [] xlist = [] while not self._stop: try: readable, writable, exceptional = select.select( self.rlist, wlist, xlist, self.timeout) except select.error, e: common.internal_print("select.error: %r".format(e), -1) break try: if not readable: if is_check: raise socket.timeout if not self.serverorclient: if self.authenticated: self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.do_dummy_packet(self.ICMP_identifier, self.ICMP_sequence) common.internal_print("Keep alive sent", 0, self.verbosity, common.DEBUG) continue for s in readable: if (s in self.rlist) and not (s is self.comms_socket): message = self.packet_reader(s, True, self.serverorclient) while True: if (len(message) < 4) or (message[0:1] != "\x45" ): #Only care about IPv4 break packetlen = struct.unpack( ">H", message[2:4])[0] # IP Total length if packetlen > len(message): message += self.packet_reader( s, False, self.serverorclient) readytogo = message[0:packetlen] message = message[packetlen:] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: # if the differece between the received and set sequences too big # some routers/firewalls just drop older sequences. If it gets # too big, we just drop the older ones and use the latest X packet # this helps on stabality. if (c.get_ICMP_received_sequence() - c.get_ICMP_sent_sequence() ) >= self.TRACKING_THRESHOLD: c.set_ICMP_sent_sequence( c.get_ICMP_received_sequence() - self.TRACKING_ADJUST) # get client related values: identifier and sequence number identifier = c.get_ICMP_sent_identifier() sequence = c.get_ICMP_sent_sequence() # queueing every packet first c.queue_put(readytogo) # are there any packets to answer? if (c.get_ICMP_received_sequence() - sequence) == 0: continue else: request_num = 0 # if there is less packet than that we have in the queue # then we cap the outgoing packet number if (c.get_ICMP_received_sequence() - sequence) < (c.queue_length()): number_to_get = ( c.get_ICMP_received_sequence() - sequence) else: # send all packets from the queue number_to_get = c.queue_length() for i in range(0, number_to_get): # get first packet readytogo = c.queue_get() # is it he last one we are sending now? if i == (number_to_get - 1): # if the last one and there is more in the queue # then we ask for dummy packets request_num = c.queue_length() # go packets go! self.send( common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa( c.get_public_ip_addr()), c.get_public_src_port()), identifier, sequence + i + 1, request_num)) sequence = (sequence + i + 1) % 65536 c.set_ICMP_sent_sequence(sequence) else: # there is no client with that IP common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: # whatever we have from the tunnel, just encapsulate it # and send it out self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.send(common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, self.ICMP_identifier, self.ICMP_sequence, 0)) #?? else: common.internal_print( "Spoofed packets, strange?!", 0, self.verbosity, common.DEBUG) continue if s is self.comms_socket: message, addr, identifier, sequence, queue_length = self.recv( ) if len(message) == 0: continue c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, identifier)) if c: c.set_ICMP_received_identifier(identifier) # packets does not arrive in order sometime # if higher sequence arrived already, then we # do not modify # 16bit integer MAX could be a bit tricky, a # threshold had to be introduced to make it # fail safe. Hacky but should work. ICMP_THRESHOLD = 100 if (sequence > c.get_ICMP_received_sequence() ) or ((sequence < ICMP_THRESHOLD) and ((sequence + 65536) > c.get_ICMP_received_sequence()) and (c.get_ICMP_received_sequence() > ICMP_THRESHOLD)): c.set_ICMP_received_sequence(sequence) else: if queue_length: common.internal_print( "sending {0} dummy packets".format( queue_length), 0, self.verbosity, common.DEBUG) for i in range(queue_length + 10): self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.do_dummy_packet( self.ICMP_identifier, self.ICMP_sequence) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE):], (addr, identifier, sequence, 0)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except (socket.error, OSError): raise if self.serverorclient: self.comms_socket.close() break except: print("another error") raise
def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # descriptor list self.rlist = [self.comms_socket] # overlapped list self.olist = [0] # event list self.elist = [hEvent_sock] # message buffer list self.mlist = [0] # id of the read object - put in this if it was read self.ulist = [] if not self.serverorclient and self.tunnel: # client mode # objects created for the tunnel and put in the corresponding # lists hEvent_pipe = win32event.CreateEvent( None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe message_buffer = win32file.AllocateReadBuffer(4096) self.rlist.append(self.tunnel) self.olist.append(overlapped_pipe) self.elist.append(hEvent_pipe) self.mlist.append(message_buffer) self.ulist.append(1) while not self._stop: try: if not self.tunnel: # check or server mode without client only with socket #message, addr = self.comms_socket.recvfrom(1508) rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if self.ulist: # there is somebody waiting to be read for idx in self.ulist: # issueing ReadFile on all not yet read mailslots/tunnel hr, _ = win32file.ReadFile(self.rlist[idx], self.mlist[idx], self.olist[idx]) if (hr != 0) and (hr != winerror.ERROR_IO_PENDING): common.internal_print( "UDP ReadFile failed: {0}".format(hr), -1) raise self.ulist = [] # waiting to get some data somewhere rc = win32event.WaitForMultipleObjects( self.elist, 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc > 0: # the tunnel or one of the mailslots got signalled self.ulist.append(rc) if (self.olist[rc].InternalHigh < 4) or (self.mlist[rc][0:1] != "\x45"): #Only care about IPv4 continue readytogo = self.mlist[rc][0:self.olist[rc]. InternalHigh] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: # if the differece between the received and set sequences too big # some routers/firewalls just drop older sequences. If it gets # too big, we just drop the older ones and use the latest X packet # this helps on stabality. if (c.get_ICMP_received_sequence() - c.get_ICMP_sent_sequence() ) >= self.TRACKING_THRESHOLD: c.set_ICMP_sent_sequence( c.get_ICMP_received_sequence() - self.TRACKING_ADJUST) # get client related values: identifier and sequence number identifier = c.get_ICMP_sent_identifier() sequence = c.get_ICMP_sent_sequence() # queueing every packet first c.queue_put(readytogo) # are there any packets to answer? if (c.get_ICMP_received_sequence() - sequence) == 0: continue else: request_num = 0 # if there is less packet than that we have in the queue # then we cap the outgoing packet number if (c.get_ICMP_received_sequence() - sequence) < (c.queue_length()): number_to_get = ( c.get_ICMP_received_sequence() - sequence) else: # send all packets from the queue number_to_get = c.queue_length() for i in range(0, number_to_get): # get first packet readytogo = c.queue_get() # is it he last one we are sending now? if i == (number_to_get - 1): # if the last one and there is more in the queue # then we ask for dummy packets request_num = c.queue_length() # go packets go! self.send(common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa( c.get_public_ip_addr()), c.get_public_src_port()), identifier, sequence + i + 1, request_num)) sequence = (sequence + i + 1) % 65536 c.set_ICMP_sent_sequence(sequence) else: # there is no client with that IP common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: # whatever we have from the tunnel, just encapsulate it # and send it out self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.send( common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, self.ICMP_identifier, self.ICMP_sequence, 0)) #?? else: common.internal_print( "Spoofed packets, strange?!", 0, self.verbosity, common.DEBUG) continue if rc == 0: # socket got signalled message, addr, identifier, sequence, queue_length = self.recv( ) if len(message) == 0: continue c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, 0)) if c: c.set_ICMP_received_identifier(identifier) # packets does not arrive in order sometime # if higher sequence arrived already, then we # do not modify # 16bit integer MAX could be a bit tricky, a # threshold had to be introduced to make it # fail safe. Hacky but should work. ICMP_THRESHOLD = 100 if (sequence > c.get_ICMP_received_sequence() ) or ((sequence < ICMP_THRESHOLD) and ((sequence + 65536) > c.get_ICMP_received_sequence()) and (c.get_ICMP_received_sequence() > ICMP_THRESHOLD)): c.set_ICMP_received_sequence(sequence) else: if queue_length: common.internal_print( "sending {0} dummy packets".format( queue_length), 0, self.verbosity, common.DEBUG) for i in range(queue_length + 10): self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.do_dummy_packet( self.ICMP_identifier, self.ICMP_sequence) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE):], (addr, identifier, sequence, 0)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except win32api.error as e: common.internal_print("UDP Exception: {0}".format(e), -1) except socket.error as se: if se.args[0] == 10054: # port is unreachable common.internal_print( "Server's port is unreachable: {0}".format(se), -1) self._stop = True return True
def communication_unix(self, is_check): self.rlist = [self.comms_socket] if not self.serverorclient and self.tunnel: self.rlist = [self.tunnel, self.comms_socket] wlist = [] xlist = [] while not self._stop: try: readable, writable, exceptional = select.select( self.rlist, wlist, xlist, self.timeout) except select.error as e: common.internal_print("select.error: %r".format(e), -1) break if (not readable) and is_check: raise socket.timeout try: for s in readable: if (s in self.rlist) and not (s is self.comms_socket): message = self.packet_reader(s, True, self.serverorclient) while True: if (len(message) < 4) or (message[0:1] != "\x45" ): #Only care about IPv4 break packetlen = struct.unpack( ">H", message[2:4])[0] # IP Total length if packetlen > len(message): message += self.packet_reader( s, False, self.serverorclient) readytogo = message[0:packetlen] message = message[packetlen:] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: self.send( common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa( c.get_public_ip_addr()), c.get_public_src_port()), None)) else: common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: self.send(common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, None)) if s is self.comms_socket: messages = self.recv() if len(messages) == 0: continue for addr in messages: for message in messages[addr]: c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, 0)) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len( common.CONTROL_CHANNEL_BYTE):], (addr, None)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer(message[ len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except (socket.error, OSError): raise if self.serverorclient: self.comms_socket.close() break except: print("another error") raise return
def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # descriptor list self.rlist = [self.comms_socket] # overlapped list self.olist = [0] # event list self.elist = [hEvent_sock] # message buffer list self.mlist = [0] # id of the read object - put in this if it was read self.ulist = [] if not self.serverorclient and self.tunnel: # client mode # objects created for the tunnel and put in the corresponding # lists hEvent_pipe = win32event.CreateEvent( None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe message_buffer = win32file.AllocateReadBuffer(4096) self.rlist.append(self.tunnel) self.olist.append(overlapped_pipe) self.elist.append(hEvent_pipe) self.mlist.append(message_buffer) self.ulist.append(1) while not self._stop: try: if not self.tunnel: # check or server mode without client only with socket rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if self.ulist: # there is somebody waiting to be read for idx in self.ulist: # issueing ReadFile on all not yet read mailslots/tunnel hr, _ = win32file.ReadFile(self.rlist[idx], self.mlist[idx], self.olist[idx]) if (hr != 0) and (hr != winerror.ERROR_IO_PENDING): common.internal_print( "UDP ReadFile failed: {0}".format(hr), -1) raise self.ulist = [] # waiting to get some data somewhere rc = win32event.WaitForMultipleObjects( self.elist, 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc > 0: # the tunnel or one of the mailslots got signalled self.ulist.append(rc) if (self.olist[rc].InternalHigh < 4) or (self.mlist[rc][0:1] != "\x45"): #Only care about IPv4 continue readytogo = self.mlist[rc][0:self.olist[rc]. InternalHigh] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: self.send( common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa(c.get_public_ip_addr()), c.get_public_src_port()), None)) else: common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: self.send(common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, None)) if rc == 0: # socket got signalled messages = self.recv() if len(messages) == 0: continue for addr in messages: for message in messages[addr]: c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, 0)) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len( common.CONTROL_CHANNEL_BYTE):], (addr, None)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer(message[ len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except win32api.error as e: common.internal_print("UDP Exception: {0}".format(e), -1) except socket.error as se: if se.args[0] == 10054: # port is unreachable common.internal_print( "Server's port is unreachable: {0}".format(se), -1) self._stop = True return True
def communication_win(self, is_check): # event, overlapped struct for the pipe or tunnel hEvent_pipe = win32event.CreateEvent(None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe # event, overlapped struct for the pipe or tunnel hEvent_rdp = win32event.CreateEvent(None, 0, 0, None) # for reading from the pipe overlapped_rdp = pywintypes.OVERLAPPED() overlapped_rdp.hEvent = hEvent_rdp # buffer for the packets message_readfile_pipe = win32file.AllocateReadBuffer(4096) message_readfile_rdp = win32file.AllocateReadBuffer(4096) # showing if we already async reading or not read_pipe = True read_rdp = False first_run = True while not self._stop: try: if not self.tunnel_r: # user is not authenticated yet, so there is no pipe # only checking the socket for data hr, _ = win32file.ReadFile(self.comms_socket, message_readfile_rdp, overlapped_rdp) if (hr == winerror.ERROR_IO_PENDING): rc = win32event.WaitForSingleObject( hEvent_rdp, int(self.timeout * 1000)) read_rdp = True else: raise rc = 0 else: # client mode so we have the socket and tunnel as well # or the client authenticated and the pipe was created if read_pipe or first_run: # no ReadFile was called before or finished, so we # are calling it again first_run = False hr, _ = win32file.ReadFile(self.tunnel_r, message_readfile_pipe, overlapped_pipe) if read_rdp: # no ReadFile was called before or finished, so we # are calling it again hr, _ = win32file.ReadFile(self.comms_socket, message_readfile_rdp, overlapped_rdp) if (hr == winerror.ERROR_IO_PENDING): # well, this was an async read, so we need to wait # until it happens rc = win32event.WaitForMultipleObjects( [hEvent_rdp, hEvent_pipe], 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if hr != 0: common.internal_print( "RDP ReadFile failed: {0}".format(hr), -1) raise if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc == 0: read_rdp = True read_pipe = False # socket got signalled # skipping header (8):length of read messages = self.recv( message_readfile_rdp[8:overlapped_rdp. InternalHigh]) # SLOW? for message in messages: # looping through the messages from socket if len(message) == 0: # this could happen when the socket died or # partial message was read. continue if common.is_control_channel(message[0:1]): # parse control messages if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE ):], None): continue else: # If the module is stopped right away, then # the channel will be closing down as well. # Because of the buffering the message will # not be sent. That is why we need to sleep time.sleep(0.5) self.stop() break if self.authenticated: try: # write packet to the tunnel self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE ):]) except OSError as e: print(e) # wut? except Exception as e: if e.args[0] == 995: common.internal_print( "Interface disappered, exiting thread: {0}" .format(e), -1) self.stop() continue print(e) if rc == 1: read_rdp = False read_pipe = True # pipe/tunnel got signalled if (overlapped_pipe.InternalHigh < 4) or (message_readfile_pipe[0:1] != "\x45"): #Only care about IPv4 # too small which should not happen or not IPv4, so we just drop it. continue # reading out the packet from the buffer and discarding the rest readytogo = message_readfile_pipe[0:overlapped_pipe. InternalHigh] self.send(common.DATA_CHANNEL_BYTE, readytogo, None) except win32api.error as e: if e.args[0] == 233: # No process is on the other end of the pipe. self._stop = True common.internal_print("Client disconnected from the pipe.", -1) continue common.internal_print("RDP Exception: {0}".format(e), -1) self.cleanup() return True