home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / oscar / rendezvous / peer.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  16.8 KB  |  459 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from util import autoassign, removedupes, myip, ip_from_bytes
  5. from util.observe import Observable
  6. from oscar.rendezvous.reactsocket import ReactSocketOne
  7. from common.timeoutsocket import TimeoutSocketMulti
  8. from common.timeoutsocket import iptuples
  9. from util.net import SocketEventMixin
  10. import struct
  11. import socket
  12. import oscar
  13. from logging import getLogger
  14. log = getLogger('oscar.peer')
  15. info = log.info
  16. from oscar.OscarUtil import tlv_list
  17. from oscar.rendezvous.proxy import ProxyHeader
  18. from pprint import pformat
  19. from common import pref
  20. from oscar.rendezvous.reactsocket import ReactSocket
  21. import oscar.capabilities as capabilities
  22. from oscar.rendezvous.rendezvous import rendezvous_message_types, rendezvous_tlvs, rendezvous_header
  23. import hooks
  24. _rdv_factories = { }
  25.  
  26. def get_rdv_factory(rdv_type):
  27.     if len(_rdv_factories) == 0:
  28.         hooks.notify('oscar.rdv.load')
  29.     
  30.     return _rdv_factories.get(rdv_type, None)
  31.  
  32.  
  33. def register_rdv_factory(name, factory):
  34.     if _rdv_factories.get(name, None) is factory:
  35.         return False
  36.     _rdv_factories[name] = factory
  37.     return True
  38.  
  39.  
  40. def initialize():
  41.     log.info('loading rendezvous handlers')
  42.     import chat
  43.     import directim
  44.     import icqrelay
  45.     import filetransfer
  46.     register_rdv_factory('livevideo', IncomingVideoChatRequest)
  47.  
  48. hooks.Hook('oscar.rdv.load').register(initialize)
  49.  
  50. def handlech2(o, rendezvous_type, screenname, cookie, message_type, data):
  51.     ch2dict = o.rdv_sessions
  52.     info('ch2 %s message from %s', rendezvous_type, screenname)
  53.     info('rendezvous_type = %r, screenname = %r, cookie = %r, message_type = %r, data = %r', rendezvous_type, screenname, cookie, message_type, data)
  54.     
  55.     try:
  56.         conn = ch2dict[cookie]
  57.         info('existing conn = %r', conn)
  58.     except KeyError:
  59.         if message_type == rendezvous_message_types.request:
  60.             factory = get_rdv_factory(rendezvous_type)
  61.             ch2dict[cookie] = conn = factory(o, screenname, cookie)
  62.             info('new conn = %r', conn)
  63.         else:
  64.             return info('%s sent ch2 %s message, unknown RDV cookie', screenname, rendezvous_message_types[message_type])
  65.         message_type == rendezvous_message_types.request
  66.  
  67.     conn.handlech2(message_type, data)
  68.  
  69. nullstr = '\x00' * 4
  70.  
  71. class OscarPeer(Observable):
  72.     
  73.     def __init__(self, protocol, screenname, cookie, capability = None):
  74.         Observable.__init__(self)
  75.         self.protocol = protocol
  76.         self.screenname = screenname
  77.         self.cookie = cookie
  78.         if capability is not None:
  79.             self.capability = capability
  80.         
  81.         self.buddy = protocol.buddies[screenname]
  82.         self.stage = 0
  83.         self.proxied = False
  84.         self.accepted = False
  85.  
  86.     
  87.     def handlech2(self, message_type, data):
  88.         info('message_type = %r, data = %r', message_type, data)
  89.         postfix = {
  90.             0: 'request',
  91.             1: 'cancel',
  92.             2: 'accept' }[message_type]
  93.         info('calling ch2' + postfix)
  94.         getattr(self, 'ch2' + postfix)(data)
  95.  
  96.     
  97.     def ch2request(self, data):
  98.         (rendtlvs, data) = oscar.unpack((('rendtlvs', 'named_tlvs', -1, rendezvous_tlvs),), data)
  99.         request_num = struct.unpack('!H', rendtlvs.request_num)[0]
  100.         info('rendtlvs = %r, data = %r, request_num = %r', rendtlvs, data, request_num)
  101.         if request_num == 1:
  102.             self.rendtlvs = rendtlvs
  103.             self.handle_request(rendtlvs)
  104.         elif request_num == 2:
  105.             info('received request num. 2: \n%s', pformat(rendtlvs))
  106.             if hasattr(rendtlvs, 'client_ip') and rendtlvs.client_ip == nullstr and rendtlvs.proxy_ip == nullstr:
  107.                 info('received a stage 3 request (\\x00\\x00\\x00\\x00)')
  108.                 info('connecting and sending an init_send to the proxy server')
  109.                 default_proxy = 'ars.oscar.aol.com'
  110.                 if self.protocol.icq:
  111.                     default_proxy = 'ars.icq.com'
  112.                 
  113.                 proxy_ip = pref('oscar.peer.proxy_server', default_proxy)
  114.                 self.stage = 3
  115.                 args = ([
  116.                     (proxy_ip, 5190)], self.initialize_proxy_send, self.failed)
  117.             elif hasattr(rendtlvs, 'proxy_flag'):
  118.                 info('receiver intervened with a stage 2 proxy')
  119.                 self.stage = 2
  120.                 self.grabaddrs(rendtlvs)
  121.                 self.needs_accept = True
  122.                 args = (self.ips, self.initialize_proxy_receive, self.failed)
  123.             else:
  124.                 info('received req num 2 redirect request')
  125.                 self.grabaddrs(rendtlvs)
  126.                 self.needs_accept = True
  127.                 self.accepted = False
  128.                 if self.ips == []:
  129.                     log.warning(rendtlvs)
  130.                 
  131.                 args = (self.ips, self.successful_connection, self.sender_establishes_proxy)
  132.             (ips, success, error) = args
  133.             self.newsock(ips, success, error)
  134.         else:
  135.             info('should try proxy now, request_num = 3')
  136.             if hasattr(rendtlvs, 'client_ip') and rendtlvs.client_ip == nullstr and rendtlvs.proxy_ip == nullstr:
  137.                 info('received a stage 3 request (\\x00\\x00\\x00\\x00)')
  138.                 info('connecting and sending an init_send to the proxy server')
  139.                 default_proxy = 'ars.oscar.aol.com'
  140.                 if self.protocol.icq:
  141.                     default_proxy = 'ars.icq.com'
  142.                 
  143.                 proxy_ip = pref('oscar.peer.proxy_server', default_proxy)
  144.                 self.stage = 3
  145.                 args = ([
  146.                     (proxy_ip, 5190)], self.initialize_proxy_send, self.failed)
  147.             else:
  148.                 self.rendtlvs = rendtlvs
  149.                 ip = self.ips_from_rdv(rendtlvs)[0]
  150.                 self.grabport(rendtlvs)
  151.                 args = ([
  152.                     (ip, self.port)], self.initialize_proxy_receive, self.failed)
  153.             (ips, success, error) = args
  154.             self.newsock(ips, success, error)
  155.  
  156.     
  157.     def failed(self):
  158.         log.error('nothing left to try.')
  159.  
  160.     
  161.     def establish_out_dc(self, message = '<HTML>', extratlvs = []):
  162.         info('message = %r, extratlvs = %r', message, extratlvs)
  163.         local_ip = pref('oscar.peer.local_ip', '')
  164.         if not local_ip:
  165.             local_ip = ''
  166.         
  167.         incoming_port = pref('oscar.peer.incoming_port', 0)
  168.         info('local_ip = %r, incoming_port = %r', local_ip, incoming_port)
  169.         proxy = pref('oscar.peer.always_proxy', None)
  170.         if proxy:
  171.             default_proxy = 'ars.oscar.aol.com'
  172.             if self.protocol.icq:
  173.                 default_proxy = 'ars.icq.com'
  174.             
  175.             proxy = pref('oscar.peer.proxy_server', default_proxy)
  176.         
  177.         info('proxy = %r', proxy)
  178.         self.newsocket().tryaccept((local_ip, incoming_port), self.incoming_conn, (lambda : info('failed direct connection')), timeout = 0)
  179.         ip = myip()
  180.         (__, port) = self.socket.getsockname()
  181.         info('sending channel 2 request asking the receiver to connect to %s:%d', ip_from_bytes(ip), port)
  182.         self.send_ch2request(1, port, ip, proxy = proxy, message = message, extratlvs = extratlvs)
  183.  
  184.     
  185.     def establish_dc(self):
  186.         self.grabaddrs(self.rendtlvs)
  187.         info('establish_dc: potential ips %r', self.ips)
  188.         if hasattr(self.rendtlvs, 'proxy_flag'):
  189.             info('STAGE 1. sender sent proxy_flag. connecting to proxy server...')
  190.             self.stage = 1
  191.             success = self.initialize_proxy_receive
  192.             error = self.stage3_request
  193.             ips = self.ips
  194.         elif pref('oscar.peer.always_proxy', False):
  195.             info('STAGE 2: always_proxy is True')
  196.             self.stage = 2
  197.             ips = [
  198.                 (pref('oscar.peer.proxy_server'), 5190)]
  199.             success = self.initialize_proxy_send
  200.             error = self.error_proxy
  201.         else:
  202.             info('attempting direct connection to %r', self.ips)
  203.             ips = self.ips
  204.             self.needs_accept = True
  205.             success = self.successful_connection
  206.             error = self.try_redirect
  207.         self.newsock(ips, success, error)
  208.  
  209.     
  210.     def successful_connection(self):
  211.         log.info('successful connection')
  212.         if not self.accepted:
  213.             self.accepted = True
  214.             if getattr(self, 'needs_accept', False):
  215.                 info('needs_accept, sending accept')
  216.                 self.send_rdv('accept')
  217.             else:
  218.                 log.info('not sending accept packet, no "needs_accept"')
  219.             log.info('on_odc_connection')
  220.             self.on_odc_connection()
  221.         else:
  222.             log.info('not calling on_odc_connection, self.accepted is already True')
  223.  
  224.     
  225.     def ips_from_rdv(self, rtlvs):
  226.         if hasattr(rtlvs, 'proxy_flag'):
  227.             return [
  228.                 ipstr(rtlvs.proxy_ip)]
  229.         return removedupes([
  230.             ipstr(rtlvs.client_ip),
  231.             ipstr(rtlvs.verified_ip)])
  232.  
  233.     
  234.     def initialize_proxy_send(self):
  235.         info('initialize_proxy_send, self.cookie = %r', self.cookie)
  236.         self.socket.receive_next(ProxyHeader._struct.size + 6, self.received_proxy_ack)
  237.         self.socket.push(ProxyHeader.initsend(self.protocol.self_buddy.name, self.cookie))
  238.  
  239.     
  240.     def initialize_proxy_receive(self):
  241.         info('sending proxy receive to %r', self.socket.getpeername())
  242.         self.socket.receive_next(ProxyHeader, self.received_proxy_ready)
  243.         proxy_initrecv = ProxyHeader.initreceive(self.protocol.self_buddy.name, self.cookie, self.port)
  244.         self.socket.push(proxy_initrecv)
  245.  
  246.     
  247.     def received_proxy_ready(self, data):
  248.         (header, data) = ProxyHeader.unpack(data)
  249.         if header.command == ProxyHeader.commands.ready:
  250.             info('proxy READY received')
  251.             self.proxied = True
  252.             self.accepted = False
  253.             self.successful_connection()
  254.         elif header.command == ProxyHeader.commands.error:
  255.             log.error('Proxy server indicated ERROR!')
  256.             self.failed()
  257.         else:
  258.             raise AssertionError('Unknown proxy command: %d' % header.command)
  259.         return header.command == ProxyHeader.commands.ready
  260.  
  261.     
  262.     def received_proxy_ack(self, data):
  263.         (header, data) = ProxyHeader.unpack(data)
  264.         if header.command == ProxyHeader.commands.ack:
  265.             info('received proxy ACK')
  266.             (proxyport, proxyip) = struct.unpack('!HI', data)
  267.             info('sending RDV request, req num %d', self.stage)
  268.             self.send_ch2request(self.stage, proxyport, None, proxyip)
  269.             self.socket.receive_next(ProxyHeader, self.received_proxy_ready)
  270.             self.needs_accept = False
  271.         else:
  272.             pformat = pformat
  273.             import pprint
  274.             log.error('Unexpected proxy packet: %r', pformat(list(iter(header))))
  275.             self.close()
  276.  
  277.     
  278.     def sender_establishes_proxy(self):
  279.         self.stage = 3
  280.         ips = [
  281.             (pref('oscar.peer.proxy_server'), 5190)]
  282.         info('sender_establishes_proxy, ips = %r', ips)
  283.         success = self.initialize_proxy_send
  284.         error = self.error_proxy
  285.         self.newsock(ips, success, error)
  286.  
  287.     
  288.     def error_proxy(self, *_a, **_k):
  289.         log.error('proxy server is being slow :(')
  290.  
  291.     
  292.     def stage3_request(self):
  293.         info('STAGE 3 - sending request...')
  294.         self.send_ch2request(2, port = None, client_ip = struct.pack('!I', 0), proxy = 0)
  295.  
  296.     
  297.     def try_redirect(self, e = None):
  298.         if getattr(self, '_done', False):
  299.             info('try_redirect was called but already done, so not asking for redirect.')
  300.             return None
  301.         self.newsocket().tryaccept(('', 0), self.incoming_conn, self.stage3_request, 3)
  302.         (__, port) = self.socket.getsockname()
  303.         info('%r is trying a redirect, listening on port %d', self, port)
  304.         info('sending channel 2 request')
  305.         self.send_ch2request(2, port, myip())
  306.  
  307.     
  308.     def incoming_conn(self, socket):
  309.         info('obtained successful incoming connection')
  310.         self.socket = ReactSocket(socket, on_close = self.on_close)
  311.         self.needs_accept = False
  312.         self.accepted = False
  313.         self.successful_connection()
  314.  
  315.     
  316.     def grabport(self, rendtlvs):
  317.         if hasattr(rendtlvs, 'external_port'):
  318.             self.port = struct.unpack('!H', rendtlvs.external_port)[0]
  319.         elif not hasattr(self, 'port'):
  320.             self.port = 5190
  321.         
  322.  
  323.     
  324.     def grabaddrs(self, rendtlvs):
  325.         self.grabport(rendtlvs)
  326.         self.ips = [ (ip, self.port) for ip in rdv_ips(rendtlvs) ]
  327.  
  328.     
  329.     def channel2(self, rendezvous_data):
  330.         info('channel2: rendezvous_data = %r', rendezvous_data)
  331.         rdv_snac = oscar.snac.x04_x06(self.screenname, self.cookie, 2, rendezvous_data)
  332.         self.protocol.send_snac(*rdv_snac)
  333.  
  334.     
  335.     def send_rdv(self, type, data = ''):
  336.         info('sending RDV %s', type)
  337.         header = rendezvous_header(type, self.cookie, self.capability)
  338.         self.channel2(oscar.OscarUtil.tlv(5, header + data))
  339.  
  340.     
  341.     def send_ch2request(self, reqnum, port, client_ip, proxy = None, message = None, extratlvs = []):
  342.         info('send_ch2request, reqnum = %r, port = %r, client_ip = %r, proxy = %r, message = %r, extratlvs = %r', reqnum, port, client_ip, proxy, message, extratlvs)
  343.         if proxy and not isinstance(proxy, (int, long)):
  344.             proxy = struct.unpack('!I', socket.inet_aton(proxy))[0]
  345.         
  346.         rz = rendezvous_tlvs
  347.         tlvs = [
  348.             (rz.request_num, 2, reqnum)]
  349.         if proxy in (None, False):
  350.             tlvs += [
  351.                 (rz.mystery,)]
  352.         else:
  353.             tlvs += [
  354.                 (rz.proxy_ip, 4, proxy),
  355.                 (rz.proxy_ip_check, 4, ~proxy)]
  356.         if message is not None:
  357.             tlvs += [
  358.                 (rz.locale, 'en'),
  359.                 (rz.encoding, 'utf-8'),
  360.                 (rz.user_message, message)]
  361.         
  362.         if client_ip is not None:
  363.             tlvs += [
  364.                 (rz.client_ip, client_ip)]
  365.         
  366.         if port is not None:
  367.             tlvs += [
  368.                 (rz.external_port, 2, port),
  369.                 (rz.port_check, 2, ~port)]
  370.         
  371.         if proxy not in (None, False):
  372.             tlvs += [
  373.                 (rz.proxy_flag,)]
  374.         
  375.         if extratlvs:
  376.             tlvs += extratlvs
  377.         
  378.         info(repr(tlvs))
  379.         self.send_rdv('request', tlv_list(*tlvs))
  380.  
  381.     
  382.     def newsock(self, ips, success, error):
  383.         if hasattr(self, 'socket'):
  384.             if isinstance(self.socket, SocketEventMixin):
  385.                 self.socket.unbind('socket_closed', self.on_close)
  386.             
  387.             
  388.             try:
  389.                 self.socket.getpeername()
  390.             except socket.error:
  391.                 e = None
  392.                 info(e)
  393.  
  394.             self.socket.close()
  395.             del self.socket
  396.         
  397.         
  398.         def assign_on_close(sock):
  399.             sock.bind_event('socket_closed', self.on_close)
  400.  
  401.         
  402.         def succ(sock):
  403.             sock.reassign()
  404.             self.socket = sock
  405.             success()
  406.  
  407.         TimeoutSocketMulti().tryconnect(iptuples(ips), succ, error, 2, cls = ReactSocketOne, provide_init = assign_on_close)
  408.  
  409.     
  410.     def newsocket(self):
  411.         if hasattr(self, 'socket'):
  412.             if isinstance(self.socket, SocketEventMixin):
  413.                 self.socket.unbind('socket_closed', self.on_close)
  414.             
  415.             
  416.             try:
  417.                 self.socket.getpeername()
  418.             except socket.error:
  419.                 e = None
  420.                 info(e)
  421.  
  422.             self.socket.close()
  423.             if isinstance(self.socket, ReactSocket):
  424.                 self.socket.cancel_timeout()
  425.             
  426.             del self.socket
  427.         
  428.         self.socket = newsock = ReactSocket(on_close = self.on_close)
  429.         info('newsocket: %r', newsock)
  430.         return newsock
  431.  
  432.  
  433. ipstr = ip_from_bytes
  434.  
  435. def rdv_ips(rendtlvs):
  436.     normal_order = ('client_ip', 'verified_ip', 'proxy_ip')
  437.     proxy_order = ('proxy_ip', 'client_ip', 'verified_ip')
  438.     order = None if hasattr(rendtlvs, 'proxy_flag') else normal_order
  439.     
  440.     ipif = lambda s: if hasattr(rendtlvs, s):
  441. ipstr(rendtlvs[s])
  442.     return None([]([], [ ipif(s) for s in order ]))
  443.  
  444.  
  445. class IncomingVideoChatRequest(OscarPeer):
  446.     capability = capabilities.by_name['livevideo']
  447.     
  448.     def handle_request(self, rendtlvs):
  449.         
  450.         def VideoChatResponseCallback(accepted = (False,)):
  451.             if not accepted:
  452.                 self.send_rdv('cancel')
  453.             else:
  454.                 log.error("Video Session accepted? But we don't support that yet!")
  455.  
  456.         self.buddy.protocol.convo_for(self.buddy).received_native_videochat_request(VideoChatResponseCallback)
  457.  
  458.  
  459.