def do_invite_message_received(self, bin_header, slp, message): '''method called when an invite message is received in the switchboard''' if slp.content_type == msn_slp.SLPMessage.CONTENT_SESSION_REQ: if 'Context' not in slp.body: common.debug('no context in p2p invite', 'p2p') return if slp.body['EUF-GUID'] == msn_slp.SLPMessage.EUFGUID_FILE: rawcontext = slp.body['Context'] context = msn_p2p.FTContext(base64.b64decode(rawcontext)) msn_p2p.FTReceiver(self, context, slp, bin_header) return elif slp.body['EUF-GUID'] == msn_slp.SLPMessage.EUFGUID_WEBCAM: rawcontext = slp.body['Context'] msn_p2p.WebcamHandler(we_invited=False, p2p=self, slp=slp) return else: data = self.get_data_by_context(slp.body['Context']) if data is not None: msn_p2p.Sender(self, bin_header, slp, data) return elif slp.content_type in (msn_slp.SLPMessage.CONTENT_TRANS_REQ, msn_slp.SLPMessage.CONTENT_TRANS_RESP): if not self.dchandler: self.dchandler = msn_p2p.DCHandler(self, bin_header, slp) else: self.dchandler.handle_invite(bin_header, slp) return common.debug('invalid invite message', 'p2p')
def makeSoapRequest(self, soapRequest, retry=True): common.debug('soap.manager makeSoapRequest(): %s' % soapRequest, 'soap') soapRequest.body = soapRequest.body.replace("&tickettoken;", self.msn.tokens['contacts.msn.com']['security']\ .replace('&', '&')) headers = { "SOAPAction": soapRequest.action, "Content-Type": "text/xml; charset=utf-8", "Host": soapRequest.host, "Content-Length": str(len(soapRequest.body)), "User-Agent": "MSN Explorer/9.0 (MSN 8.0; TmstmpExt)", "Connection": "Keep-Alive", "Cache-Control": "no-cache", } conn = None response = None if soapRequest.port == 443: conn = httplib.HTTPSConnection(soapRequest.host, soapRequest.port) else: conn = httplib.HTTPConnection(soapRequest.host, soapRequest.port) conn.request("POST", soapRequest.path, soapRequest.body, headers) response = conn.getresponse() soapResponse = SoapRequest(soapRequest.action, soapRequest.host, soapRequest.port, soapRequest.path, response.read(), soapRequest.callback, soapRequest.args) soapResponse.status = (response.status, response.reason) if soapResponse.body.count('TweenerChallenge') or \ soapResponse.body.count('LockKeyChallenge'): retry = False if retry and soapResponse.body.count('AuthenticationFailure') or \ soapResponse.body.count('PassportAuthFail'): self.msn.passportReAuth() soapResponse = self.makeSoapRequest(soapRequest, False) return soapResponse
def on_msnp2p_message_received(self, p2p, bin, slp, message): '''method called when P2PManager receives a msnp2p message we check if it is from this session, if it is, we process it if we are finished or something went wrong, we disconnect the signal ''' if 'SessionID' in slp.body: session_id = int(slp.body['SessionID']) else: session_id = int(bin.session_id) self.debug("FTSender checking") if session_id == int(self.session_id): self.debug("Mine!") if slp.method == msn_slp.SLPMessage.OK_STATUS: self.debug("Accepted") common.debug('sending data', 'p2p') p2p.emit('file-transfer-accepted', int(self.session_id), self.context, 'Me') self.emit('msnp2p-file-ready', bin.FILE_FLAG | \ bin.EACH_FLAG | bin.STORAGE_FLAG, self.data, Base.FILE_FOOTER, self.on_transfer_complete) elif slp.method == msn_slp.SLPMessage.DECLINE_STATUS or \ slp.method.startswith('BYE'): self.debug("Cancelled") p2p.emit('transfer-failed', int(self.session_id), 'cancelled') self.disconnect_handler(p2p) else: self.debug("wtf is " + str(slp.method)) elif slp.call_id == self.call_id and slp.method.startswith("BYE"): self.debug("file transfer canceled", 'p2p') p2p.emit('transfer-failed', int(self.session_id), 'cancelled') self.disconnect_handler(p2p)
def getSelected(self): '''return a tuple containing the type ("group" or "user") and the object or None''' rows = self.get_selection().get_selected_rows()[1] iterator = None if len(rows) == 1: iterator = rows[0] if iterator is None: debug('invalid iter') return (None, None) return self.getTupleByIter(iterator)
def get_data_by_context(self, context): '''receive a base64 encoded msnobj and try to return a Buffer instace with the data, if the msnobj doesnt exist, return None''' try: msnobj = self.object_manager.getByContext(context) try: return open(msnobj.filename, 'rb') except IOError: return None except (TypeError, AttributeError): common.debug('invalid msnobj in get_data_by_context', 'p2p') return None
def process(): '''run the callbacks if some response is in responseQueue''' global responseQueue while True: try: response = getNoBlock() except Queue.Empty: break common.debug("soap.manager.process(): %s" % response, "soap") if response.callback: if hasattr(response.callback, '__name__'): common.debug("soap.manager.process(): Calling %s()" % \ response.callback.__name__, "soap") response.callback(response, *response.args) return True
def run( self ): global requestQueue, responseQueue req = None while True: if not req: req = requestQueue.get() if req == 'quit' or self.msn == None: break else: try: responseQueue.put(self.makeSoapRequest(req)) except Exception, e: common.debug('soap.manager run() Error: ' + str(e), 'soap') if req.errorCount < 2: req.errorCount += 1 continue # retry req = None
def onButtonPress(self, treeview, event): if event.button == 3 and self.isTreeStore: paths = treeview.get_path_at_pos(int(event.x), int(event.y)) if paths == None: debug('invalid path') elif len(paths) > 0: iterator = self.treeModelFilter.get_iter(paths[0]) (rowType,obj) = self.getTupleByIter(iterator) self.tooltips.hideTooltip() if rowType == 'user': menu = UserMenu.UserMenu(self.controller, obj, \ self.getGroupSelected(iterator)) menu.popup(None, None, None, event.button, event.time) elif rowType == 'group' and not self.orderByStatus: menu = GroupMenu.GroupMenu(self.controller , obj) menu.popup(None, None, None, event.button, event.time) else: debug('empty paths?')
def do_invite_message_received(self, bin_header, slp, message): '''method called when an invite message is received in the switchboard''' if slp.content_type == msn_slp.SLPMessage.CONTENT_SESSION_REQ: if 'Context' not in slp.body: common.debug('no context in p2p invite', 'p2p') return if slp.body['EUF-GUID'] == msn_slp.SLPMessage.EUFGUID_FILE: # is a file rawcontext = slp.body['Context'] context = msn_p2p.FTContext(base64.b64decode(rawcontext)) # create a ft receiver here msn_p2p.FTReceiver(self, context, slp, bin_header) return elif slp.body['EUF-GUID'] == msn_slp.SLPMessage.EUFGUID_WEBCAM: # webcam invite rawcontext = slp.body['Context'] msn_p2p.WebcamHandler(False, False, self, slp) return elif slp.body['EUF-GUID'] == msn_slp.SLPMessage.EUFGUID_WEBCAM_ASK: # webcam invite rawcontext = slp.body['Context'] msn_p2p.WebcamHandler(False, True, self, slp) return else: data = self.get_data_by_context(slp.body['Context']) if data is not None: msn_p2p.Sender(self, bin_header, slp, data) return elif slp.content_type in (msn_slp.SLPMessage.CONTENT_TRANS_REQ, msn_slp.SLPMessage.CONTENT_TRANS_RESP): # its a direct connect invite if not self.dchandler: self.dchandler = msn_p2p.DCHandler(self, bin_header, slp) else: self.dchandler.handle_invite(bin_header, slp) return common.debug('invalid invite message', 'p2p')
def run(self): global requestQueue, responseQueue req = None while True: if not req: req = requestQueue.get() if req == 'quit' or self.msn == None: break else: try: responseQueue.put(self.makeSoapRequest(req)) except Exception, e: common.debug('soap.manager run() Error: ' + str(e), 'soap') if req.errorCount < 2: req.errorCount += 1 continue # retry req = None
def onButtonPress(self, treeview, event): if event.button == 3 and self.isTreeStore: paths = treeview.get_path_at_pos(int(event.x), int(event.y)) if paths == None: debug('invalid path') elif len(paths) > 0: iterator = self.treeModelFilter.get_iter(paths[0]) (rowType, obj) = self.getTupleByIter(iterator) self.tooltips.hideTooltip() if rowType == 'user': menu = UserMenu.UserMenu(self.controller, obj, \ self.getGroupSelected(iterator)) menu.popup(None, None, None, event.button, event.time) elif rowType == 'group' and not self.orderByStatus: menu = GroupMenu.GroupMenu(self.controller, obj) menu.popup(None, None, None, event.button, event.time) else: debug('empty paths?')
def debug(self, message, _channel=''): '''Emits the debug signal and displays the message in the terminal''' self.emit('debug', message) common.debug(message, 'p2p')
def put(request): global requestQueue if isinstance(request, SoapRequest): common.debug("soap.manager.put(%s)" % request, "soap") requestQueue.put(request)
def get(): global responseQueue retval = responseQueue.get() if isinstance(retval, SoapRequest): common.debug("soap.manager.get() --> %s" % retval, "soap") return retval
def address_book(proxy, callback): common.debug("soap.requests: address book", "soap") soap.manager.do_request(proxy, 'http://www.msn.com/webservices/AddressBook/ABFindAll', 'contacts.msn.com', 443, '/abservice/abservice.asmx', soap.templates.addressBook, callback)
def membership(proxy, callback): common.debug("soap.requests: membership list", "soap") soap.manager.do_request(proxy, 'http://www.msn.com/webservices/AddressBook/FindMembership', 'contacts.msn.com', 443, '/abservice/SharingService.asmx', soap.templates.membershipList, callback)
def makeSoapRequest(self, soapRequest, retry=True): common.debug('soap.manager makeSoapRequest(): %s' % soapRequest, 'soap') if soapRequest.host in self.msn.tokens: soapRequest.body = soapRequest.body.replace("&tickettoken;", self.msn.tokens[soapRequest.host]['security']\ .replace('&', '&')) # TODO: change to putheader headers = { "SOAPAction": soapRequest.action, "Content-Type": "text/xml; charset=utf-8", # "Cookie": "MSPAuth=" + self.msn.MSPAuth + ";MSPProf=" + # self.msn.MSPProf + soapRequest.extraCookie, "Host": soapRequest.host, "Content-Length": str(len(soapRequest.body)), "User-Agent": "MSN Explorer/9.0 (MSN 8.0; TmstmpExt)", "Connection": "Keep-Alive", "Cache-Control": "no-cache", "Accept-encoding": "gzip", # highly improves bandwidth usage } conn = None response = None if soapRequest.proxy and soapRequest.proxy.host: common.debug('>>> using proxy host: '+soapRequest.proxy.host) proxy_connect = 'CONNECT %s:%s HTTP/1.0\r\n'%(soapRequest.host, str(soapRequest.port)) user_agent = 'User-Agent: python\r\n' if soapRequest.proxy.user: common.debug('>>> using proxy auth user: '******':'+soapRequest.proxy.password).replace('\n','') proxy_authorization = 'Proxy-authorization: Basic '+user_pass+'\r\n' proxy_pieces = proxy_connect+proxy_authorization+user_agent+'\r\n' else: proxy_pieces = proxy_connect+user_agent+'\r\n' # now connect, very simple recv and error checking proxy = socket.socket(socket.AF_INET,socket.SOCK_STREAM) proxy.connect((soapRequest.proxy.host,int(soapRequest.proxy.port))) proxy.sendall(proxy_pieces) response = proxy.recv(8192) status=response.split()[1] if status!=str(200): raise ValueError,'Error status=%s' % str(status) # trivial setup for ssl socket if HAVE_PY25: sslconn = socket.ssl(proxy, None, None) sock = httplib.FakeSocket(proxy, sslconn) else: sock = ssl.wrap_socket(proxy, None, None) conn = httplib.HTTPConnection('localhost') conn.sock = sock else: if soapRequest.port == 443: conn = httplib.HTTPSConnection(soapRequest.host, soapRequest.port) else: conn = httplib.HTTPConnection(soapRequest.host, soapRequest.port) if soapRequest.action == 'http://www.msn.com/webservices/storage/w10/CreateDocument' or \ soapRequest.action == 'http://www.msn.com/webservices/storage/w10/DeleteRelationships': #print soapRequest.path, soapRequest.body, headers if os.name == "nt": tempfile = os.environ['TEMP'] + os.sep + "createdocumentsoap.txt" tempfile = unicode(tempfile) else: tempfile = '/tmp/createdocumentsoap.txt' f = open(tempfile, 'w') f.write(soapRequest.body) f.close() conn.request("POST", soapRequest.path, soapRequest.body, headers) response = conn.getresponse() data = response.read() isGzipd = response.getheader('Content-Encoding', '') if isGzipd == 'gzip': # data is gzipped, unzipit! cstream = StringIO.StringIO(data) gzpr = gzip.GzipFile(fileobj=cstream) data = gzpr.read() soapResponse = SoapRequest(soapRequest.proxy, soapRequest.action, soapRequest.host, soapRequest.port, soapRequest.path, data, soapRequest.callback, soapRequest.args) soapResponse.status = (response.status, response.reason) if soapResponse.body.count('TweenerChallenge') or \ soapResponse.body.count('LockKeyChallenge'): retry = False if retry and soapResponse.body.count('AuthenticationFailure') or \ soapResponse.body.count('PassportAuthFail'): self.msn.passportReAuth() soapResponse = self.makeSoapRequest(soapRequest, False) return soapResponse
def receive_message(self, body): '''called from the transport itself, body is the raw chunk, including headers, SLP, data, footer, etc''' bin_header = get_bin_header(body) if bin_header.flag == BinHeader.ACK_FLAG: return rc = None # if it's in a file if bin_header.total_data_size > bin_header.message_length and \ bin_header.flag != BinHeader.RAK_FLAG: # don't parse these #partial message common.debug("partial message", "p2p") identifier = bin_header.identifier if bin_header.flag & BinHeader.EACH_FLAG: self.emit('transfer-progress', bin_header.session_id, bin_header.data_offset) if identifier in self.incoming_pending_messages: fileobj = self.incoming_pending_messages[identifier] common.debug("follow up", "p2p") # follow-up message chunk = get_data_chunk(body, bin_header) fileobj.write(chunk) size = bin_header.data_offset + bin_header.message_length if size < bin_header.total_data_size: # don't process, it's not ready yet return common.debug("its complete!", "p2p") # it's complete! if bin_header.flag & BinHeader.STORAGE_FLAG: rc = fileobj body = None else: # build a looong message. this is a bit ugly bin_header.data_offset = 0 bin_header.message_length = bin_header.total_data_size body = str(bin_header) + fileobj.getvalue() + '\x00' * 4 del self.incoming_pending_messages[identifier] else: common.debug("first message", "p2p") # first message chunk = get_data_chunk(body, bin_header) if bin_header.flag & BinHeader.STORAGE_FLAG: newfile = tempfile.TemporaryFile() else: newfile = StringIO() newfile.write(chunk) self.incoming_pending_messages[identifier] = newfile return if bin_header.flag & BinHeader.STORAGE_FLAG and rc is None: # if the header says it's a file, it must be a file, even if # it is a single chunk. ok, yes, i know it's a hint, but # files and long invites can't be handled the same way rc = tempfile.TemporaryFile() rc.write(get_data_chunk(body, bin_header)) if bin_header.flag != BinHeader.ACK_FLAG: common.debug("acking", 'p2p') self.send_acknowledge(bin_header) # session and flag 0 means slp if body and bin_header.session_id == 0 and (bin_header.flag & 0xff) == 0: try: slp = msn_slp.SLPMessage(body[48:-4]) except msn_slp.SLPError: # since we are not 100% sure the condition is right # but we should reply with 500 internal server error slp = msn_slp.SLPMessage() #assert str(slp) == body[48:-4] else: slp = msn_slp.SLPMessage() if bin_header.flag & BinHeader.STORAGE_FLAG: common.debug(" ** FILE RECEIVED", 'p2p') # send the last progress if bin_header.flag & BinHeader.EACH_FLAG: self.emit('transfer-progress', bin_header.session_id, bin_header.data_offset) # handle it self.emit('msnp2p-file-received', bin_header, rc) elif slp and slp.method.startswith('INVITE'): common.debug(" ** INVITE", 'p2p') self.emit('invite-message-received', bin_header, slp, body) else: common.debug("** MESSAGE", 'p2p') self.emit('msnp2p-message-received', bin_header, slp, body)
def membership(proxy, callback): common.debug("soap.requests: membership list", "soap") soap.manager.do_request(proxy, 'http://www.msn.com/webservices/AddressBook/FindMembership', 'local-bay.contacts.msn.com', 443, '/abservice/SharingService.asmx', soap.templates.membershipList, callback)
def makeSoapRequest(self, soapRequest, retry=True): common.debug('soap.manager makeSoapRequest(): %s' % soapRequest, 'soap') if soapRequest.host in self.msn.tokens: soapRequest.body = soapRequest.body.replace("&tickettoken;", self.msn.tokens[soapRequest.host]['security']\ .replace('&', '&')) # TODO: change to putheader headers = { "SOAPAction": soapRequest.action, "Content-Type": "text/xml; charset=utf-8", # "Cookie": "MSPAuth=" + self.msn.MSPAuth + ";MSPProf=" + # self.msn.MSPProf + soapRequest.extraCookie, "Host": soapRequest.host, "Content-Length": str(len(soapRequest.body)), "User-Agent": "MSN Explorer/9.0 (MSN 8.0; TmstmpExt)", "Connection": "Keep-Alive", "Cache-Control": "no-cache", "Accept-encoding": "gzip", # highly improves bandwidth usage } conn = None response = None if soapRequest.proxy and soapRequest.proxy.host: common.debug('>>> using proxy host: ' + soapRequest.proxy.host) proxy_connect = 'CONNECT %s:%s HTTP/1.0\r\n' % ( soapRequest.host, str(soapRequest.port)) user_agent = 'User-Agent: python\r\n' if soapRequest.proxy.user: common.debug('>>> using proxy auth user: '******':' + soapRequest.proxy.password).replace('\n', '') proxy_authorization = 'Proxy-authorization: Basic ' + user_pass + '\r\n' proxy_pieces = proxy_connect + proxy_authorization + user_agent + '\r\n' else: proxy_pieces = proxy_connect + user_agent + '\r\n' # now connect, very simple recv and error checking proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM) proxy.connect( (soapRequest.proxy.host, int(soapRequest.proxy.port))) proxy.sendall(proxy_pieces) response = proxy.recv(8192) status = response.split()[1] if status != str(200): raise ValueError, 'Error status=%s' % str(status) # trivial setup for ssl socket if HAVE_PY25: sslconn = socket.ssl(proxy, None, None) sock = httplib.FakeSocket(proxy, sslconn) else: sock = ssl.wrap_socket(proxy, None, None) conn = httplib.HTTPConnection('localhost') conn.sock = sock else: if soapRequest.port == 443: conn = httplib.HTTPSConnection(soapRequest.host, soapRequest.port) else: conn = httplib.HTTPConnection(soapRequest.host, soapRequest.port) if soapRequest.action == 'http://www.msn.com/webservices/storage/w10/CreateDocument' or \ soapRequest.action == 'http://www.msn.com/webservices/storage/w10/DeleteRelationships': #print soapRequest.path, soapRequest.body, headers if os.name == "nt": tempfile = os.environ[ 'TEMP'] + os.sep + "createdocumentsoap.txt" tempfile = unicode(tempfile) else: tempfile = '/tmp/createdocumentsoap.txt' f = open(tempfile, 'w') f.write(soapRequest.body) f.close() conn.request("POST", soapRequest.path, soapRequest.body, headers) response = conn.getresponse() data = response.read() isGzipd = response.getheader('Content-Encoding', '') if isGzipd == 'gzip': # data is gzipped, unzipit! cstream = StringIO.StringIO(data) gzpr = gzip.GzipFile(fileobj=cstream) data = gzpr.read() soapResponse = SoapRequest(soapRequest.proxy, soapRequest.action, soapRequest.host, soapRequest.port, soapRequest.path, data, soapRequest.callback, soapRequest.args) soapResponse.status = (response.status, response.reason) if soapResponse.body.count('TweenerChallenge') or \ soapResponse.body.count('LockKeyChallenge'): retry = False if retry and soapResponse.body.count('AuthenticationFailure') or \ soapResponse.body.count('PassportAuthFail'): self.msn.passportReAuth() soapResponse = self.makeSoapRequest(soapRequest, False) return soapResponse
def address_book(proxy, callback): common.debug("soap.requests: address book", "soap") soap.manager.do_request(proxy, 'http://www.msn.com/webservices/AddressBook/ABFindAll', 'local-bay.contacts.msn.com', 443, '/abservice/abservice.asmx', soap.templates.addressBook, callback)
def receive_message(self, body): '''called from the transport itself, body is the raw chunk, including headers, SLP, data, footer, etc''' bin_header = get_bin_header(body) if bin_header.flag == BinHeader.ACK_FLAG: return rc = None # if it's in a file if bin_header.total_data_size > bin_header.message_length and \ bin_header.flag != BinHeader.RAK_FLAG: # don't parse these common.debug("partial message", "p2p") identifier = bin_header.identifier if bin_header.flag & BinHeader.EACH_FLAG: self.emit('transfer-progress', bin_header.session_id, bin_header.data_offset) if identifier in self.incoming_pending_messages: fileobj = self.incoming_pending_messages[identifier] common.debug("follow up", "p2p") chunk = get_data_chunk(body, bin_header) fileobj.write(chunk) size = bin_header.data_offset + bin_header.message_length if size < bin_header.total_data_size: return common.debug("its complete!", "p2p") if bin_header.flag & BinHeader.STORAGE_FLAG: rc = fileobj body = None else: bin_header.data_offset = 0 bin_header.message_length = bin_header.total_data_size body = str(bin_header) + fileobj.getvalue() + '\x00' * 4 del self.incoming_pending_messages[identifier] else: common.debug("first message", "p2p") chunk = get_data_chunk(body, bin_header) if bin_header.flag & BinHeader.STORAGE_FLAG: newfile = tempfile.TemporaryFile() else: newfile = StringIO() newfile.write(chunk) self.incoming_pending_messages[identifier] = newfile return if bin_header.flag & BinHeader.STORAGE_FLAG and rc is None: rc = tempfile.TemporaryFile() rc.write(get_data_chunk(body, bin_header)) if bin_header.flag != BinHeader.ACK_FLAG: common.debug("acking", 'p2p') self.send_acknowledge(bin_header) if body and bin_header.session_id == 0 and bin_header.flag == 0: try: slp = msn_slp.SLPMessage(body[48:-4]) except msn_slp.SLPError: slp = msn_slp.SLPMessage() else: slp = msn_slp.SLPMessage() if bin_header.flag & BinHeader.STORAGE_FLAG: common.debug(" ** FILE RECEIVED", 'p2p') if bin_header.flag & BinHeader.EACH_FLAG: self.emit('transfer-progress', bin_header.session_id, bin_header.data_offset) self.emit('msnp2p-file-received', bin_header, rc) elif slp and slp.method.startswith('INVITE'): common.debug(" ** INVITE", 'p2p') self.emit('invite-message-received', bin_header, slp, body) else: common.debug("** MESSAGE", 'p2p') self.emit('msnp2p-message-received', bin_header, slp, body)