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