switch to Python 3, defusedxml and select

- add method handle_xmpp_stanza that uses select to check socket for available
  data and feed the XML parser
- use defusedxml for more robust XML parsing
This commit is contained in:
Jan Dittberner 2015-02-10 09:35:37 +01:00
parent 9edc6e0c3e
commit 3ef552ffc1

View file

@ -1,12 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import from __future__ import absolute_import
from datetime import datetime from datetime import datetime
import socket import socket
from xml.sax import make_parser from select import select
from xml.sax.handler import ContentHandler, feature_namespaces from xml.sax.handler import ContentHandler, feature_namespaces
from defusedxml.sax import make_parser
import nagiosplugin import nagiosplugin
@ -47,7 +48,7 @@ class XmppClientServerResponseHandler(ContentHandler):
if self.inelem[-1] == (NS_XMPP_SASL, 'mechanism'): if self.inelem[-1] == (NS_XMPP_SASL, 'mechanism'):
self.mechanisms.append(content) self.mechanisms.append(content)
else: else:
print self.inelem, content print(self.inelem, content)
def is_valid_start(self): def is_valid_start(self):
return True # TODO: some real implementation return True # TODO: some real implementation
@ -107,22 +108,27 @@ class Xmpp(nagiosplugin.Resource):
def handle_server(self, xmppsocket): def handle_server(self, xmppsocket):
pass pass
def is_valid_client_response(self, xmldata): def handle_xmpp_stanza(self, xmppsocket, message_str):
self.parser.feed(xmldata) xmppsocket.sendall(message_str.encode('utf-8'))
return self.contenthandler.is_valid_start() while True:
rready, wready, xready = select([xmppsocket], [], [], 0.1)
if xmppsocket in rready:
data = xmppsocket.recv(4096)
if not data: break
self.parser.feed(data.decode('utf-8'))
else:
break
def handle_client(self, xmppsocket): def handle_client(self, xmppsocket):
xmppsocket.sendall(( self.handle_xmpp_stanza(xmppsocket, (
"<?xml version='1.0' ?><stream:stream to='{servername}' " "<?xml version='1.0' ?><stream:stream to='{servername}' "
"xmlns='jabber:client' " "xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams' " "xmlns:stream='http://etherx.jabber.org/streams' "
"version='1.0'>" "version='1.0'>"
).format(servername=self.servername)) ).format(servername=self.servername))
if not self.is_valid_client_response(xmppsocket.recv(4096)): if not self.contenthandler.is_valid_start():
raise XmppException("no valid response to XMPP client request") raise XmppException("no valid response to XMPP client request")
xmppsocket.sendall("</stream:stream>") self.handle_xmpp_stanza(xmppsocket, "</stream:stream>")
self.parser.feed(xmppsocket.recv(4096))
def probe(self): def probe(self):
start = datetime.now() start = datetime.now()