home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / pyxmpp / streamsasl.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  8.8 KB  |  299 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __revision__ = '$Id: streamsasl.py 720 2010-04-20 10:31:35Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import base64
  7. import logging
  8. from pyxmpp.jid import JID
  9. from pyxmpp import sasl
  10. from pyxmpp.exceptions import StreamAuthenticationError, SASLNotAvailable, SASLMechanismNotAvailable, SASLAuthenticationFailed
  11. SASL_NS = 'urn:ietf:params:xml:ns:xmpp-sasl'
  12.  
  13. class StreamSASLMixIn(sasl.PasswordManager):
  14.     
  15.     def __init__(self, sasl_mechanisms = ()):
  16.         sasl.PasswordManager.__init__(self)
  17.         if sasl_mechanisms:
  18.             self.sasl_mechanisms = sasl_mechanisms
  19.         else:
  20.             self.sasl_mechanisms = []
  21.         self._StreamSASLMixIn__logger = logging.getLogger('pyxmpp.StreamSASLMixIn')
  22.  
  23.     
  24.     def _reset_sasl(self):
  25.         self.peer_sasl_mechanisms = None
  26.         self.authenticator = None
  27.  
  28.     
  29.     def _make_stream_sasl_features(self, features):
  30.         if self.sasl_mechanisms and not (self.authenticated):
  31.             ml = features.newChild(None, 'mechanisms', None)
  32.             ns = ml.newNs(SASL_NS, None)
  33.             ml.setNs(ns)
  34.             for m in self.sasl_mechanisms:
  35.                 if m in sasl.all_mechanisms:
  36.                     ml.newTextChild(None, 'mechanism', m)
  37.                     continue
  38.             
  39.         
  40.         return features
  41.  
  42.     
  43.     def _handle_sasl_features(self):
  44.         ctxt = self.doc_in.xpathNewContext()
  45.         ctxt.setContextNode(self.features)
  46.         ctxt.xpathRegisterNs('sasl', SASL_NS)
  47.         
  48.         try:
  49.             sasl_mechanisms_n = ctxt.xpathEval('sasl:mechanisms/sasl:mechanism')
  50.         finally:
  51.             ctxt.xpathFreeContext()
  52.  
  53.         if sasl_mechanisms_n:
  54.             self._StreamSASLMixIn__logger.debug('SASL support found')
  55.             self.peer_sasl_mechanisms = []
  56.             for n in sasl_mechanisms_n:
  57.                 self.peer_sasl_mechanisms.append(n.getContent())
  58.             
  59.         
  60.  
  61.     
  62.     def _process_node_sasl(self, xmlnode):
  63.         ns_uri = xmlnode.ns().getContent()
  64.         if ns_uri == SASL_NS:
  65.             self._process_sasl_node(xmlnode)
  66.             return True
  67.         return False
  68.  
  69.     
  70.     def _process_sasl_node(self, xmlnode):
  71.         if self.initiator:
  72.             if not self.authenticator:
  73.                 self._StreamSASLMixIn__logger.debug('Unexpected SASL response: %r' % xmlnode.serialize())
  74.                 ret = False
  75.             elif xmlnode.name == 'challenge':
  76.                 ret = self._process_sasl_challenge(xmlnode.getContent())
  77.             elif xmlnode.name == 'success':
  78.                 ret = self._process_sasl_success(xmlnode.getContent())
  79.             elif xmlnode.name == 'failure':
  80.                 ret = self._process_sasl_failure(xmlnode)
  81.             else:
  82.                 self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
  83.                 ret = False
  84.         elif xmlnode.name == 'auth':
  85.             mechanism = xmlnode.prop('mechanism')
  86.             ret = self._process_sasl_auth(mechanism, xmlnode.getContent())
  87.         
  88.         if xmlnode.name == 'response':
  89.             ret = self._process_sasl_response(xmlnode.getContent())
  90.         
  91.         if xmlnode.name == 'abort':
  92.             ret = self._process_sasl_abort()
  93.         else:
  94.             self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
  95.             ret = False
  96.         return ret
  97.  
  98.     
  99.     def _process_sasl_auth(self, mechanism, content):
  100.         if self.authenticator:
  101.             self._StreamSASLMixIn__logger.debug('Authentication already started')
  102.             return False
  103.         self.auth_method_used = 'sasl:' + mechanism
  104.         self.authenticator = sasl.server_authenticator_factory(mechanism, self)
  105.         r = self.authenticator.start(base64.decodestring(content))
  106.         if isinstance(r, sasl.Success):
  107.             el_name = 'success'
  108.             content = r.base64()
  109.         elif isinstance(r, sasl.Challenge):
  110.             el_name = 'challenge'
  111.             content = r.base64()
  112.         else:
  113.             el_name = 'failure'
  114.             content = None
  115.         root = self.doc_out.getRootElement()
  116.         xmlnode = root.newChild(None, el_name, None)
  117.         ns = xmlnode.newNs(SASL_NS, None)
  118.         xmlnode.setNs(ns)
  119.         if content:
  120.             xmlnode.setContent(content)
  121.         
  122.         if isinstance(r, sasl.Failure):
  123.             xmlnode.newChild(None, r.reason, None)
  124.         
  125.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  126.         xmlnode.unlinkNode()
  127.         xmlnode.freeNode()
  128.         if isinstance(r, sasl.Success):
  129.             if r.authzid:
  130.                 self.peer = JID(r.authzid)
  131.             else:
  132.                 self.peer = JID(r.username, self.me.domain)
  133.             self.peer_authenticated = 1
  134.             self.state_change('authenticated', self.peer)
  135.             self._post_auth()
  136.         
  137.         if isinstance(r, sasl.Failure):
  138.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  139.         isinstance(r, sasl.Failure)
  140.         return True
  141.  
  142.     
  143.     def _process_sasl_challenge(self, content):
  144.         if not self.authenticator:
  145.             self._StreamSASLMixIn__logger.debug('Unexpected SASL challenge')
  146.             return False
  147.         r = self.authenticator.challenge(base64.decodestring(content))
  148.         if isinstance(r, sasl.Response):
  149.             el_name = 'response'
  150.             content = r.base64()
  151.         else:
  152.             el_name = 'abort'
  153.             content = None
  154.         root = self.doc_out.getRootElement()
  155.         xmlnode = root.newChild(None, el_name, None)
  156.         ns = xmlnode.newNs(SASL_NS, None)
  157.         xmlnode.setNs(ns)
  158.         if content:
  159.             xmlnode.setContent(content)
  160.         
  161.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  162.         xmlnode.unlinkNode()
  163.         xmlnode.freeNode()
  164.         if isinstance(r, sasl.Failure):
  165.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  166.         isinstance(r, sasl.Failure)
  167.         return True
  168.  
  169.     
  170.     def _process_sasl_response(self, content):
  171.         if not self.authenticator:
  172.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  173.             return 0
  174.         r = self.authenticator.response(base64.decodestring(content))
  175.         if isinstance(r, sasl.Success):
  176.             el_name = 'success'
  177.             content = r.base64()
  178.         elif isinstance(r, sasl.Challenge):
  179.             el_name = 'challenge'
  180.             content = r.base64()
  181.         else:
  182.             el_name = 'failure'
  183.             content = None
  184.         root = self.doc_out.getRootElement()
  185.         xmlnode = root.newChild(None, el_name, None)
  186.         ns = xmlnode.newNs(SASL_NS, None)
  187.         xmlnode.setNs(ns)
  188.         if content:
  189.             xmlnode.setContent(content)
  190.         
  191.         if isinstance(r, sasl.Failure):
  192.             xmlnode.newChild(None, r.reason, None)
  193.         
  194.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  195.         xmlnode.unlinkNode()
  196.         xmlnode.freeNode()
  197.         if isinstance(r, sasl.Success):
  198.             authzid = r.authzid
  199.             if authzid:
  200.                 self.peer = JID(r.authzid)
  201.             else:
  202.                 self.peer = JID(r.username, self.me.domain)
  203.             self.peer_authenticated = 1
  204.             self._restart_stream()
  205.             self.state_change('authenticated', self.peer)
  206.             self._post_auth()
  207.         
  208.         if isinstance(r, sasl.Failure):
  209.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  210.         isinstance(r, sasl.Failure)
  211.         return 1
  212.  
  213.     
  214.     def _process_sasl_success(self, content):
  215.         if not self.authenticator:
  216.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  217.             return False
  218.         r = self.authenticator.finish(base64.decodestring(content))
  219.         if isinstance(r, sasl.Success):
  220.             self._StreamSASLMixIn__logger.debug('SASL authentication succeeded')
  221.             if r.authzid:
  222.                 self.me = JID(r.authzid)
  223.             else:
  224.                 self.me = self.me
  225.             self.authenticated = 1
  226.             self._restart_stream()
  227.             self.state_change('authenticated', self.me)
  228.             self._post_auth()
  229.         else:
  230.             self._StreamSASLMixIn__logger.debug('SASL authentication failed')
  231.             raise SASLAuthenticationFailed, 'Additional success data procesing failed'
  232.         return isinstance(r, sasl.Success)
  233.  
  234.     
  235.     def _process_sasl_failure(self, xmlnode):
  236.         if not self.authenticator:
  237.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  238.             return False
  239.         self._StreamSASLMixIn__logger.debug('SASL authentication failed: %r' % (xmlnode.serialize(),))
  240.         raise SASLAuthenticationFailed, 'SASL authentication failed'
  241.  
  242.     
  243.     def _process_sasl_abort(self):
  244.         if not self.authenticator:
  245.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  246.             return False
  247.         self.authenticator = None
  248.         self._StreamSASLMixIn__logger.debug('SASL authentication aborted')
  249.         return True
  250.  
  251.     
  252.     def _sasl_authenticate(self, username, authzid, mechanism = None):
  253.         if not self.initiator:
  254.             raise SASLAuthenticationFailed, 'Only initiating entity start SASL authentication'
  255.         self.initiator
  256.         while not self.features:
  257.             self._StreamSASLMixIn__logger.debug('Waiting for features')
  258.             self._read()
  259.         if not self.peer_sasl_mechanisms:
  260.             raise SASLNotAvailable, "Peer doesn't support SASL"
  261.         self.peer_sasl_mechanisms
  262.         if not mechanism:
  263.             mechanism = None
  264.             for m in self.sasl_mechanisms:
  265.                 if m in self.peer_sasl_mechanisms:
  266.                     mechanism = m
  267.                     break
  268.                     continue
  269.             
  270.             if not mechanism:
  271.                 raise SASLMechanismNotAvailable, "Peer doesn't support any of our SASL mechanisms"
  272.             mechanism
  273.             self._StreamSASLMixIn__logger.debug('Our mechanism: %r' % (mechanism,))
  274.         elif mechanism not in self.peer_sasl_mechanisms:
  275.             raise SASLMechanismNotAvailable, '%s is not available' % (mechanism,)
  276.         
  277.         self.auth_method_used = 'sasl:' + mechanism
  278.         self.authenticator = sasl.client_authenticator_factory(mechanism, self)
  279.         initial_response = self.authenticator.start(username, authzid)
  280.         if not isinstance(initial_response, sasl.Response):
  281.             raise SASLAuthenticationFailed, 'SASL initiation failed'
  282.         isinstance(initial_response, sasl.Response)
  283.         root = self.doc_out.getRootElement()
  284.         xmlnode = root.newChild(None, 'auth', None)
  285.         ns = xmlnode.newNs(SASL_NS, None)
  286.         xmlnode.setNs(ns)
  287.         xmlnode.setProp('mechanism', mechanism)
  288.         if initial_response.data:
  289.             if initial_response.encode:
  290.                 xmlnode.setContent(initial_response.base64())
  291.             else:
  292.                 xmlnode.setContent(initial_response.data)
  293.         
  294.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  295.         xmlnode.unlinkNode()
  296.         xmlnode.freeNode()
  297.  
  298.  
  299.