home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / pyxmpp / jabber / clientstream.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  11.8 KB  |  392 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: clientstream.py 683 2008-12-05 18:25:45Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6.  
  7. try:
  8.     import hashlib
  9.     sha_factory = hashlib.sha1
  10. except ImportError:
  11.     import sha
  12.     sha_factory = sha.new
  13.  
  14. import logging
  15. from pyxmpp.iq import Iq
  16. from pyxmpp.utils import to_utf8, from_utf8
  17. from pyxmpp.jid import JID
  18. from pyxmpp.clientstream import ClientStream
  19. from pyxmpp.jabber.register import Register
  20. from pyxmpp.exceptions import ClientStreamError, LegacyAuthenticationError, RegistrationError
  21.  
  22. class LegacyClientStream(ClientStream):
  23.     
  24.     def __init__(self, jid, password = None, server = None, port = 5222, auth_methods = ('sasl:DIGEST-MD5', 'digest'), tls_settings = None, keepalive = 0, owner = None):
  25.         (self.authenticated, self.available_auth_methods, self.auth_stanza, self.peer_authenticated, self.auth_method_used, self.registration_callback, self.registration_form, self._LegacyClientStream__register) = (None, None, None, None, None, None, None, None)
  26.         ClientStream.__init__(self, jid, password, server, port, auth_methods, tls_settings, keepalive, owner)
  27.         self._LegacyClientStream__logger = logging.getLogger('pyxmpp.jabber.LegacyClientStream')
  28.  
  29.     
  30.     def _reset(self):
  31.         ClientStream._reset(self)
  32.         self.available_auth_methods = None
  33.         self.auth_stanza = None
  34.         self.registration_callback = None
  35.  
  36.     
  37.     def _post_connect(self):
  38.         if not self.initiator:
  39.             if 'plain' in self.auth_methods or 'digest' in self.auth_methods:
  40.                 self.set_iq_get_handler('query', 'jabber:iq:auth', self.auth_in_stage1)
  41.                 self.set_iq_set_handler('query', 'jabber:iq:auth', self.auth_in_stage2)
  42.             
  43.         elif self.registration_callback:
  44.             iq = Iq(stanza_type = 'get')
  45.             iq.set_content(Register())
  46.             self.set_response_handlers(iq, self.registration_form_received, self.registration_error)
  47.             self.send(iq)
  48.             return None
  49.         
  50.         ClientStream._post_connect(self)
  51.  
  52.     
  53.     def _post_auth(self):
  54.         ClientStream._post_auth(self)
  55.         if not self.initiator:
  56.             self.unset_iq_get_handler('query', 'jabber:iq:auth')
  57.             self.unset_iq_set_handler('query', 'jabber:iq:auth')
  58.         
  59.  
  60.     
  61.     def _try_auth(self):
  62.         if self.authenticated:
  63.             self._LegacyClientStream__logger.debug('try_auth: already authenticated')
  64.             return None
  65.         
  66.         self._LegacyClientStream__logger.debug('trying auth: %r' % (self._auth_methods_left,))
  67.         if not self._auth_methods_left:
  68.             raise LegacyAuthenticationError, 'No allowed authentication methods available'
  69.         
  70.         method = self._auth_methods_left[0]
  71.         if method.startswith('sasl:'):
  72.             return ClientStream._try_auth(self)
  73.         elif method not in ('plain', 'digest'):
  74.             self._auth_methods_left.pop(0)
  75.             self._LegacyClientStream__logger.debug('Skipping unknown auth method: %s' % method)
  76.             return self._try_auth()
  77.         elif self.available_auth_methods is not None:
  78.             self._auth_methods_left.pop(0)
  79.             if method in self.available_auth_methods:
  80.                 self.auth_method_used = method
  81.                 if method == 'digest':
  82.                     self._digest_auth_stage2(self.auth_stanza)
  83.                 else:
  84.                     self._plain_auth_stage2(self.auth_stanza)
  85.                 self.auth_stanza = None
  86.                 return None
  87.             else:
  88.                 self._LegacyClientStream__logger.debug('Skipping unavailable auth method: %s' % method)
  89.                 return self._try_auth()
  90.         else:
  91.             self._auth_stage1()
  92.  
  93.     
  94.     def auth_in_stage1(self, stanza):
  95.         self.lock.acquire()
  96.         
  97.         try:
  98.             if 'plain' not in self.auth_methods and 'digest' not in self.auth_methods:
  99.                 iq = stanza.make_error_response('not-allowed')
  100.                 self.send(iq)
  101.                 return None
  102.             
  103.             iq = stanza.make_result_response()
  104.             q = iq.new_query('jabber:iq:auth')
  105.             q.newChild(None, 'username', None)
  106.             q.newChild(None, 'resource', None)
  107.             if 'plain' in self.auth_methods:
  108.                 q.newChild(None, 'password', None)
  109.             
  110.             if 'digest' in self.auth_methods:
  111.                 q.newChild(None, 'digest', None)
  112.             
  113.             self.send(iq)
  114.             iq.free()
  115.         finally:
  116.             self.lock.release()
  117.  
  118.  
  119.     
  120.     def auth_in_stage2(self, stanza):
  121.         self.lock.acquire()
  122.         
  123.         try:
  124.             if 'plain' not in self.auth_methods and 'digest' not in self.auth_methods:
  125.                 iq = stanza.make_error_response('not-allowed')
  126.                 self.send(iq)
  127.                 return None
  128.             
  129.             username = stanza.xpath_eval('a:query/a:username', {
  130.                 'a': 'jabber:iq:auth' })
  131.             if username:
  132.                 username = from_utf8(username[0].getContent())
  133.             
  134.             resource = stanza.xpath_eval('a:query/a:resource', {
  135.                 'a': 'jabber:iq:auth' })
  136.             if resource:
  137.                 resource = from_utf8(resource[0].getContent())
  138.             
  139.             if not username or not resource:
  140.                 self._LegacyClientStream__logger.debug('No username or resource found in auth request')
  141.                 iq = stanza.make_error_response('bad-request')
  142.                 self.send(iq)
  143.                 return None
  144.             
  145.             if stanza.xpath_eval('a:query/a:password', {
  146.                 'a': 'jabber:iq:auth' }):
  147.                 if 'plain' not in self.auth_methods:
  148.                     iq = stanza.make_error_response('not-allowed')
  149.                     self.send(iq)
  150.                     return None
  151.                 else:
  152.                     return self._plain_auth_in_stage2(username, resource, stanza)
  153.             
  154.             if stanza.xpath_eval('a:query/a:digest', {
  155.                 'a': 'jabber:iq:auth' }):
  156.                 if 'plain' not in self.auth_methods:
  157.                     iq = stanza.make_error_response('not-allowed')
  158.                     self.send(iq)
  159.                     return None
  160.                 else:
  161.                     return self._digest_auth_in_stage2(username, resource, stanza)
  162.         finally:
  163.             self.lock.release()
  164.  
  165.  
  166.     
  167.     def _auth_stage1(self):
  168.         iq = Iq(stanza_type = 'get')
  169.         q = iq.new_query('jabber:iq:auth')
  170.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  171.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  172.         self.send(iq)
  173.         self.set_response_handlers(iq, self.auth_stage2, self.auth_error, self.auth_timeout, timeout = 60)
  174.         iq.free()
  175.  
  176.     
  177.     def auth_timeout(self):
  178.         self.lock.acquire()
  179.         
  180.         try:
  181.             self._LegacyClientStream__logger.debug('Timeout while waiting for jabber:iq:auth result')
  182.             if self._auth_methods_left:
  183.                 self._auth_methods_left.pop(0)
  184.         finally:
  185.             self.lock.release()
  186.  
  187.  
  188.     
  189.     def auth_error(self, stanza):
  190.         self.lock.acquire()
  191.         
  192.         try:
  193.             err = stanza.get_error()
  194.             ae = err.xpath_eval('e:*', {
  195.                 'e': 'jabber:iq:auth:error' })
  196.             if ae:
  197.                 ae = ae[0].name
  198.             else:
  199.                 ae = err.get_condition().name
  200.             raise LegacyAuthenticationError, 'Authentication error condition: %s' % (ae,)
  201.         finally:
  202.             self.lock.release()
  203.  
  204.  
  205.     
  206.     def auth_stage2(self, stanza):
  207.         self.lock.acquire()
  208.         
  209.         try:
  210.             self._LegacyClientStream__logger.debug('Procesing auth response...')
  211.             self.available_auth_methods = []
  212.             if stanza.xpath_eval('a:query/a:digest', {
  213.                 'a': 'jabber:iq:auth' }) and self.stream_id:
  214.                 self.available_auth_methods.append('digest')
  215.             
  216.             if stanza.xpath_eval('a:query/a:password', {
  217.                 'a': 'jabber:iq:auth' }):
  218.                 self.available_auth_methods.append('plain')
  219.             
  220.             self.auth_stanza = stanza.copy()
  221.             self._try_auth()
  222.         finally:
  223.             self.lock.release()
  224.  
  225.  
  226.     
  227.     def _plain_auth_stage2(self, _unused):
  228.         iq = Iq(stanza_type = 'set')
  229.         q = iq.new_query('jabber:iq:auth')
  230.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  231.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  232.         q.newTextChild(None, 'password', to_utf8(self.password))
  233.         self.send(iq)
  234.         self.set_response_handlers(iq, self.auth_finish, self.auth_error)
  235.         iq.free()
  236.  
  237.     
  238.     def _plain_auth_in_stage2(self, username, _unused, stanza):
  239.         password = stanza.xpath_eval('a:query/a:password', {
  240.             'a': 'jabber:iq:auth' })
  241.         if password:
  242.             password = from_utf8(password[0].getContent())
  243.         
  244.         if not password:
  245.             self._LegacyClientStream__logger.debug('No password found in plain auth request')
  246.             iq = stanza.make_error_response('bad-request')
  247.             self.send(iq)
  248.             return None
  249.         
  250.         if self.check_password(username, password):
  251.             iq = stanza.make_result_response()
  252.             self.send(iq)
  253.             self.peer_authenticated = True
  254.             self.auth_method_used = 'plain'
  255.             self.state_change('authorized', self.peer)
  256.             self._post_auth()
  257.         else:
  258.             self._LegacyClientStream__logger.debug('Plain auth failed')
  259.             iq = stanza.make_error_response('bad-request')
  260.             e = iq.get_error()
  261.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  262.             self.send(iq)
  263.  
  264.     
  265.     def _digest_auth_stage2(self, _unused):
  266.         iq = Iq(stanza_type = 'set')
  267.         q = iq.new_query('jabber:iq:auth')
  268.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  269.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  270.         digest = sha_factory(to_utf8(self.stream_id) + to_utf8(self.password)).hexdigest()
  271.         q.newTextChild(None, 'digest', digest)
  272.         self.send(iq)
  273.         self.set_response_handlers(iq, self.auth_finish, self.auth_error)
  274.         iq.free()
  275.  
  276.     
  277.     def _digest_auth_in_stage2(self, username, _unused, stanza):
  278.         digest = stanza.xpath_eval('a:query/a:digest', {
  279.             'a': 'jabber:iq:auth' })
  280.         if digest:
  281.             digest = digest[0].getContent()
  282.         
  283.         if not digest:
  284.             self._LegacyClientStream__logger.debug('No digest found in digest auth request')
  285.             iq = stanza.make_error_response('bad-request')
  286.             self.send(iq)
  287.             return None
  288.         
  289.         (password, pwformat) = self.get_password(username)
  290.         if not password or pwformat != 'plain':
  291.             iq = stanza.make_error_response('bad-request')
  292.             e = iq.get_error()
  293.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  294.             self.send(iq)
  295.             return None
  296.         
  297.         mydigest = sha_factory(to_utf8(self.stream_id) + to_utf8(password)).hexdigest()
  298.         if mydigest == digest:
  299.             iq = stanza.make_result_response()
  300.             self.send(iq)
  301.             self.peer_authenticated = True
  302.             self.auth_method_used = 'digest'
  303.             self.state_change('authorized', self.peer)
  304.             self._post_auth()
  305.         else:
  306.             self._LegacyClientStream__logger.debug('Digest auth failed: %r != %r' % (digest, mydigest))
  307.             iq = stanza.make_error_response('bad-request')
  308.             e = iq.get_error()
  309.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  310.             self.send(iq)
  311.  
  312.     
  313.     def auth_finish(self, _unused):
  314.         self.lock.acquire()
  315.         
  316.         try:
  317.             self._LegacyClientStream__logger.debug('Authenticated')
  318.             self.authenticated = True
  319.             self.state_change('authorized', self.my_jid)
  320.             self._post_auth()
  321.         finally:
  322.             self.lock.release()
  323.  
  324.  
  325.     
  326.     def registration_error(self, stanza):
  327.         self.lock.acquire()
  328.         
  329.         try:
  330.             err = stanza.get_error()
  331.             ae = err.xpath_eval('e:*', {
  332.                 'e': 'jabber:iq:auth:error' })
  333.             if ae:
  334.                 ae = ae[0].name
  335.             else:
  336.                 ae = err.get_condition().name
  337.             raise RegistrationError, 'Authentication error condition: %s' % (ae,)
  338.         finally:
  339.             self.lock.release()
  340.  
  341.  
  342.     
  343.     def registration_form_received(self, stanza):
  344.         self.lock.acquire()
  345.         
  346.         try:
  347.             self._LegacyClientStream__register = Register(stanza.get_query())
  348.             self.registration_callback(stanza, self._LegacyClientStream__register.get_form())
  349.         finally:
  350.             self.lock.release()
  351.  
  352.  
  353.     
  354.     def submit_registration_form(self, form):
  355.         self.lock.acquire()
  356.         
  357.         try:
  358.             if form and form.type != 'cancel':
  359.                 self.registration_form = form
  360.                 iq = Iq(stanza_type = 'set')
  361.                 iq.set_content(self._LegacyClientStream__register.submit_form(form))
  362.                 self.set_response_handlers(iq, self.registration_success, self.registration_error)
  363.                 self.send(iq)
  364.             else:
  365.                 self._LegacyClientStream__register = None
  366.         finally:
  367.             self.lock.release()
  368.  
  369.  
  370.     
  371.     def registration_success(self, stanza):
  372.         _unused = stanza
  373.         self.lock.acquire()
  374.         
  375.         try:
  376.             self.state_change('registered', self.registration_form)
  377.             if 'FORM_TYPE' in self.registration_form and self.registration_form['FORM_TYPE'].value == 'jabber:iq:register':
  378.                 if 'username' in self.registration_form:
  379.                     self.my_jid = JID(self.registration_form['username'].value, self.my_jid.domain, self.my_jid.resource)
  380.                 
  381.                 if 'password' in self.registration_form:
  382.                     self.password = self.registration_form['password'].value
  383.                 
  384.             
  385.             self.registration_callback = None
  386.             self._post_connect()
  387.         finally:
  388.             self.lock.release()
  389.  
  390.  
  391.  
  392.