def findAPILocation(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if ( status != 0 ): return (status, briefing, message, None) status, briefing, message, data = apiLookup(domain_url) if ( status != 0 ): status = 2 briefing = "This test was skipped because previous test <strong>api_server_lookup</strong> has failed.<br/>" new_message = briefing new_message += "Reason:<br/>" new_message += "<br/>" + message return (status, briefing, new_message, None) status, briefing, message, output = apiConnection(domain_url) if ( status != 0 ): status = 2 briefing = "This test was skipped because previous test <strong>api_server_connection</strong> has failed.<br/>" new_message = briefing new_message = "Reason:<br/>" new_message += "<br/>" + message return (status, briefing, new_message, None) api_location = "%(protocol)s://%(domain)s%(path)s/" % data status = 0 briefing = "HTTP API location for buddycloud domain at %s found: %s" % (domain_url, api_location) message = briefing return (status, briefing, message, api_location)
def performSRVLookup(domain_url, srv_name, srv_description, srv_port): (status, briefing, message, output) = domainNameLookup(domain_url) if ( status != 0 ): return (status, briefing, message, None) answers = [] query_for_SRV_record = None try: resolver = dns.resolver.Resolver() resolver.nameservers = [ getAuthoritativeNameserver(domain_url) ] resolver.lifetime = 5 query_for_SRV_record = resolver.query(srv_name+domain_url, dns.rdatatype.SRV) except (NXDOMAIN, NoAnswer, Timeout): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) except Exception, e: if ( str(e) == "" or str(e) == ("%s. does not exist." % domain_url) ): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) status = 2 briefing = "A problem happened while searching for the %s:" % srv_description briefing += " <strong>" + srv_name + domain_url + "</strong>!" message = "Something odd happened while we were searching for the %s:" % srv_description message += " <strong>" + srv_name + domain_url + "</strong>!" message += "<br/>This is the exception we got: {"+str(e)+"}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <a href='https://github.com/buddycloud/buddycloud-tests-framework/issues'>our issue tracker</a> if you think so." return (status, briefing, message, None)
def findAPILocation(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if (status != 0): return (status, briefing, message, None) status, briefing, message, data = apiLookup(domain_url) if (status != 0): status = 2 briefing = "This test was skipped because previous test <strong>api_server_lookup</strong> has failed.<br/>" new_message = briefing new_message += "Reason:<br/>" new_message += "<br/>" + message return (status, briefing, new_message, None) status, briefing, message, output = apiConnection(domain_url) if (status != 0): status = 2 briefing = "This test was skipped because previous test <strong>api_server_connection</strong> has failed.<br/>" new_message = briefing new_message = "Reason:<br/>" new_message += "<br/>" + message return (status, briefing, new_message, None) api_location = "%(protocol)s://%(domain)s%(path)s/" % data status = 0 briefing = "HTTP API location for buddycloud domain at %s found: %s" % ( domain_url, api_location) message = briefing return (status, briefing, message, api_location)
def testFunction(domain_url): view = {"domain_url":domain_url} if ( domainNameLookup(domain_url)[0] != 0 ): view["warning"] = "%s not found!" % (domain_url) return warning(view) try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) if ( nameserver ): resolver.nameservers = [ nameserver ] answer = resolver.query("_buddycloud-api._tcp."+domain_url, dns.rdatatype.TXT) except Exception as e: return no_record(view) else: txt_answer = answer[0].to_text() view["record"] = txt_answer for test in record_well_formedness_tests: if ( not test[0](txt_answer) ): view["error"] = code("TXT record") + " is malformed! " + test[1] return record_error(view) domain = txt_answer[txt_answer.find("host=")+5: txt_answer.find(" ", txt_answer.find("host=")+5)] port = txt_answer[txt_answer.find("port=")+5: txt_answer.find(" ", txt_answer.find("port=")+5)] path = txt_answer[txt_answer.find("path=")+5: txt_answer.find(" ", txt_answer.find("path=")+5)] protocol = txt_answer[txt_answer.find("protocol=")+9: txt_answer.find(" ", txt_answer.find("protocol=")+9)] if ( protocol.lower() != "https" ): view["error"] = code("TXT record") + "\'s " + bold("protocol") + "\ attribute must have value set to " + code("https") + "!" return record_error(view) output = { 'protocol' : protocol, 'domain' : domain, 'port' : port, 'path' : path } return record_correct(view, output)
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if status != 0: return (status, briefing, message, None) classified_as = checkMediaServerPresence(domain_url) description = descriptions[classified_as] % ("<strong>" + domain_url + "</strong>") briefing = description.split("<br/>")[0] message = description if classified_as == "MEDIASERVER_UP": status = 0 elif classified_as == "SERVER_ERROR" or classified_as == "NOT_MEDIASERVER_UP": status = 1 else: status = 2 return (status, briefing, message, None)
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if (status != 0): return (status, briefing, message, None) classified_as = checkPusherServerPresence(domain_url) description = descriptions[classified_as] % ("<strong>" + domain_url + "</strong>") briefing = description.split("<br/>")[0] message = description if (classified_as == "PUSHERSERVER_UP"): status = 0 elif (classified_as == "SERVER_ERROR" or classified_as == "NOT_PUSHERSERVER_UP"): status = 1 else: status = 2 return (status, briefing, message, None)
def performSRVLookup(domain_url, srv_name, srv_description, srv_port): (status, briefing, message, output) = domainNameLookup(domain_url) if (status != 0): return (status, briefing, message, None) answers = [] query_for_SRV_record = None try: resolver = dns.resolver.Resolver() resolver.nameservers = [getAuthoritativeNameserver(domain_url)] resolver.lifetime = 5 query_for_SRV_record = resolver.query(srv_name + domain_url, dns.rdatatype.SRV) except (NXDOMAIN, NoAnswer, Timeout): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) except Exception, e: if (str(e) == "" or str(e) == ("%s. does not exist." % domain_url)): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) status = 2 briefing = "A problem happened while searching for the %s:" % srv_description briefing += " <strong>" + srv_name + domain_url + "</strong>!" message = "Something odd happened while we were searching for the %s:" % srv_description message += " <strong>" + srv_name + domain_url + "</strong>!" message += "<br/>This is the exception we got: {" + str(e) + "}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <a href='https://github.com/buddycloud/buddycloud-tests-framework/issues'>our issue tracker</a> if you think so." return (status, briefing, message, None)
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if (status != 0): return (status, briefing, message, None) query_for_TXT_record = None try: resolver = dns.resolver.Resolver() resolver.nameservers = [getAuthoritativeNameserver(domain_url)] resolver.lifetime = 5 query_for_TXT_record = resolver.query( "_buddycloud-api._tcp." + domain_url, dns.rdatatype.TXT) except (NXDOMAIN, NoAnswer): return noTXTRecord(domain_url) except Exception as e: if (str(e) == "" or str(e) == ("%s. does not exist." % domain_url)): return noTXTRecord(domain_url) status = 2 briefing = "A problem happened while searching for the API server TXT record:" briefing += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message = "Something odd happened while we were searching for the API server TXT record:" message += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message += "<br/>This is the exception we got: {" + str(e) + "}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <a href='https://github.com/buddycloud/buddycloud-tests-framework/issues'>our issue tracker</a> if you think so." return (status, briefing, message, None) classified_records = {} for answer in query_for_TXT_record: classified = classifyTXTRecord(str(answer)) if not classified['type'] in classified_records: classified_records[classified['type']] = [] classified_records[classified['type']].append(classified) if (len(classified_records.get('INFO_MISSING', [])) != 0 or len(classified_records.get('MALFORMED', [])) != 0 or len(classified_records.get('NOT_HTTPS', [])) != 0): status = 1 briefing = "We detected incorrect API server TXT records at domain" briefing += " <strong>%s</strong>." % domain_url message = "We detected you set up the following incorrect API" message += " server TXT records.<br/>" message += "You must have just one correct API server SRV record.<br/>" message += "These are the SRV records we found and their problems: <br/><br/>" for record in classified_records.get('INFO_MISSING', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) for record in classified_records.get('MALFORMED', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) if (len(classified_records.get('MALFORMED', [])) != 0): message += "The API server TXT record must always have a <em>version</em>, <em>host</em>," message += " <em>protocol</em>, <em>path</em> and <em>port</em>.<br/>" message += "<strong>Each of these properties must be defined within double quotes and separated by spaces only</strong>.<br/>" message += "For example, assuming that the server running buddycloud will be named: <strong><em>buddycloud." message += domain_url + "</em></strong>," message += "<br/>here you are a TXT record that should work:<br/>" message += "<strong>_buddycloud-api._tcp." + domain_url + "\tIN TXT \"v=1.0\" \"host=buddycloud." message += domain_url + "\" \"protocol=https\" \"path=/api\" \"port=433\"</strong><br/>" message += "<br/>Please not that your API server TXT record won't be correct until it contains proper" message += " information regarding the <em>version</em>, <em>host</em>, <em>protocol<em/>, <em>path</em> and <em>port</em>.<br/>" for record in classified_records.get('NOT_HTTPS', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) if (len(classified_records.get('NOT_HTTPS', [])) != 0): message += "Please ensure your API server will run with HTTPS enabled.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) == 0: status = 1 briefing = "No correct API server TXT record found at " briefing += "domain <strong>%s</strong>!<br/>" % domain_url message = briefing + "<br/>" message += "You must have one correct API server SRV record.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) > 1: status = 1 briefing = "We found multiple correct API server TXT records!" message = briefing + "<br/>" message += "But really, you should have just one.<br/>" message += "These are the records we found: <br/><br/>" else: status = 0 briefing = "API server TXT record found: " briefing += "<strong>%s</strong>" % classified_records['CORRECT'][0][ 'record'] message = "Congratulations! You have set up your API server " message += "TXT record correctly.<br/><br/>" for record in classified_records.get('CORRECT', []): message += ("<strong>%s://%s:%s%s</strong><br/><em>%s</em><br/><br/>" % (record['protocol'], record['domain'], record['port'], record['path'], record['record'])) r = classified_records['CORRECT'][0] return (status, briefing, message, { 'protocol': r['protocol'], 'domain': r['domain'], 'port': r['port'], 'path': r['path'] })
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if ( status != 0 ): return (status, briefing, message, None) query_for_TXT_record = None try: resolver = dns.resolver.Resolver() resolver.nameservers = [ getAuthoritativeNameserver(domain_url) ] resolver.lifetime = 5 query_for_TXT_record = resolver.query("_buddycloud-api._tcp."+domain_url, dns.rdatatype.TXT) except (NXDOMAIN, NoAnswer): return noTXTRecord(domain_url) except Exception as e: if ( str(e) == "" or str(e) == ("%s. does not exist." % domain_url) ): return noTXTRecord(domain_url) status = 2 briefing = "A problem happened while searching for the API server TXT record:" briefing += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message = "Something odd happened while we were searching for the API server TXT record:" message += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message += "<br/>This is the exception we got: {"+str(e)+"}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <a href='https://github.com/buddycloud/buddycloud-tests-framework/issues'>our issue tracker</a> if you think so." return (status, briefing, message, None) classified_records = {} for answer in query_for_TXT_record: classified = classifyTXTRecord(str(answer)) if not classified['type'] in classified_records: classified_records[classified['type']] = [] classified_records[classified['type']].append(classified) if ( len(classified_records.get('INFO_MISSING', [])) != 0 or len(classified_records.get('MALFORMED', [])) != 0 or len(classified_records.get('NOT_HTTPS', [])) != 0 ): status = 1 briefing = "We detected incorrect API server TXT records at domain" briefing += " <strong>%s</strong>." % domain_url message = "We detected you set up the following incorrect API" message += " server TXT records.<br/>" message += "You must have just one correct API server SRV record.<br/>" message += "These are the SRV records we found and their problems: <br/><br/>" for record in classified_records.get('INFO_MISSING', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) for record in classified_records.get('MALFORMED', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) if ( len(classified_records.get('MALFORMED', [])) != 0 ): message += "The API server TXT record must always have a <em>version</em>, <em>host</em>," message += " <em>protocol</em>, <em>path</em> and <em>port</em>.<br/>" message += "<strong>Each of these properties must be defined within double quotes and separated by spaces only</strong>.<br/>" message += "For example, assuming that the server running buddycloud will be named: <strong><em>buddycloud." message += domain_url + "</em></strong>," message += "<br/>here you are a TXT record that should work:<br/>" message += "<strong>_buddycloud-api._tcp." + domain_url + "\tIN TXT \"v=1.0\" \"host=buddycloud." message += domain_url + "\" \"protocol=https\" \"path=/api\" \"port=433\"</strong><br/>" message += "<br/>Please not that your API server TXT record won't be correct until it contains proper" message += " information regarding the <em>version</em>, <em>host</em>, <em>protocol<em/>, <em>path</em> and <em>port</em>.<br/>" for record in classified_records.get('NOT_HTTPS', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) if ( len(classified_records.get('NOT_HTTPS', [])) != 0 ): message += "Please ensure your API server will run with HTTPS enabled.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) == 0: status = 1 briefing = "No correct API server TXT record found at " briefing += "domain <strong>%s</strong>!<br/>" % domain_url message = briefing + "<br/>" message += "You must have one correct API server SRV record.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) > 1: status = 1 briefing = "We found multiple correct API server TXT records!" message = briefing + "<br/>" message += "But really, you should have just one.<br/>" message += "These are the records we found: <br/><br/>" else: status = 0 briefing = "API server TXT record found: " briefing += "<strong>%s</strong>" % classified_records['CORRECT'][0]['record'] message = "Congratulations! You have set up your API server " message += "TXT record correctly.<br/><br/>" for record in classified_records.get('CORRECT', []): message += ("<strong>%s://%s:%s%s</strong><br/><em>%s</em><br/><br/>" % (record['protocol'], record['domain'], record['port'], record['path'], record['record'])) r = classified_records['CORRECT'][0] return (status, briefing, message, { 'protocol' : r['protocol'], 'domain' : r['domain'], 'port' : r['port'], 'path' : r['path'] })
def testFunction(domain_url): view = {"domain_url":domain_url} if ( domainNameLookup(domain_url)[0] != 0 ): view["warning"] = "%s not found!" % (domain_url) return warning(view) (status, b, m, answers) = xmppServerServiceRecordLookup(domain_url) if ( status != 0 ): wiew["warning"] = "XMPP Server of domain %s not found!" % (domain_url) return warning(view) xmpp = sleekxmpp.ClientXMPP("*****@*****.**", "ei3tseq") situation = {} for answer in answers: conn_address = answer["domain"], answer["port"] view["xmpp_server"] = conn_address[0] if ( not xmpp.connect(conn_address, reattempt=False, use_ssl=False, use_tls=False) ): situation[conn_address] = make_output_builder(view, xmpp_connection_problem) continue xmpp.process(block=False) try: DISCO_ITEMS_NS = 'http://jabber.org/protocol/disco#items' iq = xmpp.make_iq_get(queryxmlns=DISCO_ITEMS_NS, ito=domain_url, ifrom=xmpp.boundjid) try: view["disco_type"] = "disco#items" response = iq.send(block=True, timeout=5) except Exception as e: if ( str(e) != "" ): view["error"] = str(e) situation[conn_address] = make_output_builder(view, xmpp_disco_query_send_error) continue if ( len(response.xml.findall("iq[@type='error']")) != 0 ): view["error"] = response.xml.findall("iq[@type='error']")[0] situation[conn_address] = make_output_builder(view, xmpp_server_error) continue its = response.xml.findall( "{%s}query/{%s}item" % ((DISCO_ITEMS_NS,)*2)) for item in its: item_jid = item.attrib['jid'] DISCO_INFO_NS = 'http://jabber.org/protocol/disco#info' iq = xmpp.make_iq_get(queryxmlns=DISCO_INFO_NS, ito=item_jid, ifrom=xmpp.boundjid) try: view["disco_type"] = "disco#info" response = iq.send(block=True, timeout=5) except Exception as e: if ( str(e) != "" ): view["error"] = str(e) situation[conn_address] = make_output_builder(view, xmpp_disco_query_send_error) continue if ( len(response.xml.findall("iq[@type='error']")) != 0 ): view["error"] = response.xml.findall("iq[@type='error']")[0] situation[conn_address] = make_output_builder(view, xmpp_server_error) continue ids = response.xml.findall( "{%s}query/{%s}identity" % ((DISCO_INFO_NS,)*2)) for identity in ids: identity_category = identity.attrib['category'] identity_type = identity.attrib['type'] view["discovery"] = True view["channel_server"] = item_jid if ( identity_category == 'pubsub' and identity_type == 'channels' ): try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) resolver.nameservers = [nameserver] resolver.lifetime = 5 PTR_name = "_buddycloud-server._tcp." + domain_url answer = resolver.query(PTR_name, dns.rdatatype.PTR) except Exception: pass else: #TODO check if PTR record and DISCO are pointing # to the same place -- they must! view["ptr_record"] = True return is_buddycloud_enabled(view) if not conn_address in situation: situation[conn_address] = make_output_builder(view, not_buddycloud_enabled) finally: xmpp.disconnect() try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) resolver.nameservers = [nameserver] resolver.lifetime = 5 PTR_name = "_buddycloud-server._tcp." + domain_url answer = resolver.query(PTR_name, dns.rdatatype.PTR) except (NXDOMAIN, NoAnswer, Timeout): pass except Exception: pass else: view["ptr_record"] = True #view["channel_server"] = answer return is_buddycloud_enabled(view) if ( len(situation) == 1 ): return situation[situation.keys()[0]]() view["xmpp_servers"] = [] status = 2 for xmpp_server in situation: output = situation[xmpp_server]() if ( output[0] == 1 ): status = 1 view["xmpp_servers"].append({ "name" : "%s through port %s" %(xmpp_server), "error" : output[2] }) view["status"] = status return multiple_problems(view)
def performSRVLookup(domain_url, srv_name, srv_description, srv_port): (status, briefing, message, output) = domainNameLookup(domain_url) if status != 0: return (status, briefing, message, None) answers = [] query_for_SRV_record = None try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) if nameserver: resolver.nameservers = [nameserver] query_for_SRV_record = resolver.query(srv_name + domain_url, dns.rdatatype.SRV) except (NXDOMAIN, NoAnswer, Timeout): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) except Exception as e: if str(e) == "" or str(e) == ("%s. does not exist." % domain_url): return no_SRV_record(domain_url, srv_name, srv_description, srv_port) status = 2 briefing = "A problem happened while searching for the %s:" % srv_description briefing += " <strong>" + srv_name + domain_url + "</strong>!" message = "Something odd happened while we were searching for the %s:" % srv_description message += " <strong>" + srv_name + domain_url + "</strong>!" message += "<br/>This is the exception we got: {" + str(e) + "}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <a href='https://github.com/buddycloud/buddycloud-tests-framework/issues'>our issue tracker</a> if you think so." return (status, briefing, message, None) for answer in query_for_SRV_record: try: domain = answer.target.to_text()[:-1] port = str(answer.port) answers.append({"domain": domain, "port": port, "priority": answer.priority, "weight": answer.weight}) except Exception: continue SRV_records = [] for i in range(len(answers)): SRV_record = srv_name + domain_url + " IN SRV " SRV_record += answers[i]["port"] + " " + str(answers[i]["domain"]) SRV_records.append(SRV_record) status = 0 briefing = srv_description + "s found: <strong>" + string.join(SRV_records, " | ") + "</strong>" message = "Congratulations! You have set up your SRV records correctly." message += "<br/>These were the %ss we found:<br/>" % srv_description message += "<strong><br/>" + string.join(SRV_records, "<br/>") + "<br/></strong>" message += "<br/>Now, we expect that at least one of them is pointing to an A record" message += " that will ultimately guide us to your buddycloud server." return (status, briefing, message, answers)
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if ( status != 0 ): return (status, briefing, message, None) classified_as = checkBuddycloudCompatibility(domain_url) description = descriptions[classified_as] % ("<strong>"+domain_url+"</strong>") briefing = description.split("<br/>")[0] message = description if ( classified_as == "BUDDYCLOUD_ENABLED" ): status = 0 elif ( classified_as == "SERVER_ERROR" or classified_as == "NOT_BUDDYCLOUD_ENABLED" ): status = 1 (sts, brf, mes, out) = buddycloudChannelSRVLookup(domain_url) if ( sts != 0 ): message += "<br/>You need to set up a SRV record " (sts2, brf2, mes2, xmpp_server_names) = xmppServerServiceRecordLookup(domain_url) if ( sts2 != 0 ): message += "similar to the following:" message += "<br/><br/><em>(assuming your XMPP server is called" message += " <strong>bc.%s</strong>)</em><br/>" % domain_url message += "<strong>_xmpp-server._tcp.channels." + domain_url + "." message += "\tSRV\t5\t0\t5269\tbc.%s.</strong>" % domain_url else: message += "exactly like the following:" if ( len(xmpp_server_names) > 1 ): message += " (only one of them)" message += "<br/><br/>" for xmpp_server in xmpp_server_names: xmpp_server = xmpp_server['domain'] message += "<strong>_xmpp-server._tcp.channels.%s." %domain_url message += "\tSRV\t5\t0\t5269\t%s.<br/><br/></strong>" %xmpp_server else: message += "<br/>Please ensure your buddycloud channel server is running " message += "at <strong>%s</strong> and if that's not the case, run:<br/>" % domain_url message += "<br/><strong>sudo /etc/init.d/buddycloud-server" message += " start</strong><br/><br/>...to start your buddycloud channel server.<br/>" message += "See more information at <a href='https://buddycloud.org/wiki/Install" message += "#buddycloud_Channel_Server' target='_blank'>" message += "https://buddycloud.org/wiki/Install#buddycloud_Channel_Server</a>." else: status = 2 (sts, brf, mes, out) = xmppServerConnection(domain_url) if ( sts != 0 ): status = 1 message = briefing + "<br/>" message += "Reason: <br/>" message += mes return (status, briefing, message, None) return (status, briefing, message, None)
def testFunction(domain_url): view = {"domain_url":domain_url} if ( domainNameLookup(domain_url)[0] != 0 ): view["warning"] = "%s not found!" % (domain_url) return warning(view) xmpp = create_xmpp_client() conn_address = 'crater.buddycloud.org', 5222 disco_situation = None if ( not xmpp.connect(conn_address) ): disco_situation = make_output_builder(view, xmpp_connection_problem) else: xmpp.process(block=False) try: DISCO_ITEMS_NS = 'http://jabber.org/protocol/disco#items' iq = xmpp.make_iq_get(queryxmlns=DISCO_ITEMS_NS, ito=domain_url, ifrom=xmpp.boundjid) class DiscoItemsFailedException(Exception): pass try: view["disco_type"] = "disco#items" response = iq.send(block=True, timeout=config.IQ_TIMEOUT) except Exception as e: if ( str(e) != "" ): view["error"] = str(e) disco_situation = make_output_builder(view, xmpp_disco_query_send_error) raise DiscoItemsFailedException() if ( len(response.xml.findall("iq[@type='error']")) != 0 ): view["error"] = response.xml.findall("iq[@type='error']")[0] disco_situation = make_output_builder(view, xmpp_server_error) raise DiscoItemsFailedException() its = response.xml.findall( "{%s}query/{%s}item" % ((DISCO_ITEMS_NS,)*2)) for item in its: item_jid = item.attrib['jid'] DISCO_INFO_NS = 'http://jabber.org/protocol/disco#info' iq = xmpp.make_iq_get(queryxmlns=DISCO_INFO_NS, ito=item_jid, ifrom=xmpp.boundjid) try: view["disco_type"] = "disco#info" view["xmpp_server"] = item_jid response = iq.send(block=True, timeout=config.IQ_TIMEOUT) except Exception as e: if ( str(e) != "" ): view["error"] = str(e) disco_situation = make_output_builder(view, xmpp_disco_query_send_error) continue if ( len(response.xml.findall("iq[@type='error']")) != 0 ): view["error"] = response.xml.findall("iq[@type='error']")[0] disco_situation = make_output_builder(view, xmpp_server_error) continue ids = response.xml.findall( "{%s}query/{%s}identity" % ((DISCO_INFO_NS,)*2)) for identity in ids: identity_category = identity.attrib['category'] identity_type = identity.attrib['type'] if ( identity_category == 'pubsub' and identity_type == 'channels' ): view["discovery"] = True view["channel_server"] = item_jid try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) if ( nameserver ): resolver.nameservers = [nameserver] TXT_name = "_bcloud-server._tcp." + domain_url answer = resolver.query(TXT_name, dns.rdatatype.TXT) except Exception: pass else: view["txt_record"] = True txt_answer = answer[0].to_text() if ( len(txt_answer) == 0 ): txt_answer = "(Blank record)" view["record"] = txt_answer for test in record_well_formedness_tests: if ( not test[0](txt_answer) ): view["error"] = code("TXT record") + " is malformed! " + test[1] return record_error(view) answer_jid = txt_answer[txt_answer.find("server=")+7:txt_answer.find(" ", txt_answer.find("server=")+7)] if ( item_jid != answer_jid ): view["channel_server2"] = answer_jid return buddycloud_enabled_with_conflict(view) return is_buddycloud_enabled(view) if disco_situation == None: disco_situation = make_output_builder(view, not_buddycloud_enabled) except DiscoItemsFailedException: pass finally: xmpp.disconnect() try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) if ( nameserver ): resolver.nameservers = [nameserver] TXT_name = "_bcloud-server._tcp." + domain_url answer = resolver.query(TXT_name, dns.rdatatype.TXT) except Exception: return disco_situation() else: view["txt_record"] = True txt_answer = answer[0].to_text() if ( len(txt_answer) == 0 ): txt_answer = "(Blank record)" view["record"] = txt_answer for test in record_well_formedness_tests: if ( not test[0](txt_answer) ): view["error"] = code("TXT record") + " is malformed! " + test[1] return record_error(view) answer_jid = txt_answer[txt_answer.find("server=")+7:txt_answer.find(" ", txt_answer.find("server=")+7)] view["channel_server"] = answer_jid return is_buddycloud_enabled(view)
def testFunction(domain_url): (status, briefing, message, output) = domainNameLookup(domain_url) if ( status != 0 ): return (status, briefing, message, None) query_for_TXT_record = None try: resolver = dns.resolver.Resolver() resolver.nameservers = [ getAuthoritativeNameserver(domain_url) ] resolver.lifetime = 5 query_for_TXT_record = resolver.query("_buddycloud-api._tcp."+domain_url, dns.rdatatype.TXT) except (NXDOMAIN, NoAnswer): return noTXTRecord(domain_url) except Exception as e: if ( str(e) == "" or str(e) == ("%s. does not exist." % domain_url) ): return noTXTRecord(domain_url) status = 2 briefing = "A problem happened while searching for the API server TXT record:" briefing += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message = "Something odd happened while we were searching for the API server TXT record:" message += " <strong>_buddycloud-api._tcp." + domain_url + "</strong>!" message += "<br/>This is the exception we got: {"+str(e)+"}" message += "<br/>It is probably a temporary issue with domain " + domain_url + "." message += "<br/>But it could also be a bug in our Inspector." message += " Let us know at <email> if you think so." return (status, briefing, message, None) classified_records = {} for answer in query_for_TXT_record: classified = classifyTXTRecord(str(answer)) if not classified['type'] in classified_records: classified_records[classified['type']] = [] classified_records[classified['type']].append(classified) if ( len(classified_records.get('INFO_MISSING', [])) != 0 or len(classified_records.get('MALFORMED', [])) != 0 or len(classified_records.get('NOT_HTTPS', [])) != 0 ): status = 1 briefing = "We detected incorrect API server TXT records at domain" briefing += " <strong>%s</strong>." % domain_url message = "We detected you set up the following incorrect API" message += " server TXT records.<br/>" message += "Really you must have just one correct API server SRV record.<br/>" message += "These are the SRV records we found and their problems: <br/><br/>" for record in classified_records.get('INFO_MISSING', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) for record in classified_records.get('MALFORMED', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) for record in classified_records.get('NOT_HTTPS', []): message += ("<strong>%s</strong><br/><em>%s</em><br/><br/>" % (record['description'], record['record'])) if ( len(classified_records.get('NOT_HTTPS', [])) != 0 ): message += "Please ensure your API server will run with HTTPS enabled.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) == 0: status = 1 briefing = "No correct API server TXT record found at " briefing += "domain <strong>%s</strong>!<br/>" % domain_url message = briefing + "<br/>" message += "You must have one correct API server SRV record.<br/>" message += "See <a href='https://buddycloud.org/wiki/Install#buddycloud_DNS' target='_blank'" message += " >https://buddycloud.org/wiki/Install#buddycloud_DNS</a> for more information.<br/>" return (status, briefing, message, None) elif len(classified_records.get('CORRECT', [])) > 1: status = 1 briefing = "We found multiple correct API server TXT records!" message = briefing + "<br/>" message += "But really, you should have just one.<br/>" message += "These are the records we found: <br/><br/>" else: status = 0 briefing = "API server TXT record found: " briefing += "<strong>%s</strong>" % classified_records['CORRECT'][0]['record'] message = "Congratulations! You have set up your API server " message += "TXT record correctly.<br/><br/>" for record in classified_records.get('CORRECT', []): message += ("<strong>%s://%s:%s%s</strong><br/><em>%s</em><br/><br/>" % (record['protocol'], record['domain'], record['port'], record['path'], record['record'])) r = classified_records['CORRECT'][0] return (status, briefing, message, { 'protocol' : r['protocol'], 'domain' : r['domain'], 'port' : r['port'], 'path' : r['path'] })
def testFunction(domain_url): view = {"domain_url": domain_url} if (domainNameLookup(domain_url)[0] != 0): view["warning"] = "%s not found!" % (domain_url) return warning(view) (status, b, m, answers) = xmppServerServiceRecordLookup(domain_url) if (status != 0): wiew["warning"] = "XMPP Server of domain %s not found!" % (domain_url) return warning(view) xmpp = sleekxmpp.ClientXMPP("*****@*****.**", "ei3tseq") situation = {} for answer in answers: conn_address = answer["domain"], answer["port"] view["xmpp_server"] = conn_address[0] if (not xmpp.connect( conn_address, reattempt=False, use_ssl=False, use_tls=False)): situation[conn_address] = make_output_builder( view, xmpp_connection_problem) continue xmpp.process(block=False) try: DISCO_ITEMS_NS = 'http://jabber.org/protocol/disco#items' iq = xmpp.make_iq_get(queryxmlns=DISCO_ITEMS_NS, ito=domain_url, ifrom=xmpp.boundjid) try: view["disco_type"] = "disco#items" response = iq.send(block=True, timeout=5) except Exception as e: if (str(e) != ""): view["error"] = str(e) situation[conn_address] = make_output_builder( view, xmpp_disco_query_send_error) continue if (len(response.xml.findall("iq[@type='error']")) != 0): view["error"] = response.xml.findall("iq[@type='error']")[0] situation[conn_address] = make_output_builder( view, xmpp_server_error) continue its = response.xml.findall("{%s}query/{%s}item" % ((DISCO_ITEMS_NS, ) * 2)) for item in its: item_jid = item.attrib['jid'] DISCO_INFO_NS = 'http://jabber.org/protocol/disco#info' iq = xmpp.make_iq_get(queryxmlns=DISCO_INFO_NS, ito=item_jid, ifrom=xmpp.boundjid) try: view["disco_type"] = "disco#info" response = iq.send(block=True, timeout=5) except Exception as e: if (str(e) != ""): view["error"] = str(e) situation[conn_address] = make_output_builder( view, xmpp_disco_query_send_error) continue if (len(response.xml.findall("iq[@type='error']")) != 0): view["error"] = response.xml.findall( "iq[@type='error']")[0] situation[conn_address] = make_output_builder( view, xmpp_server_error) continue ids = response.xml.findall("{%s}query/{%s}identity" % ((DISCO_INFO_NS, ) * 2)) for identity in ids: identity_category = identity.attrib['category'] identity_type = identity.attrib['type'] view["discovery"] = True view["channel_server"] = item_jid if (identity_category == 'pubsub' and identity_type == 'channels'): try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) resolver.nameservers = [nameserver] resolver.lifetime = 5 PTR_name = "_buddycloud-server._tcp." + domain_url answer = resolver.query(PTR_name, dns.rdatatype.PTR) except Exception: pass else: #TODO check if PTR record and DISCO are pointing # to the same place -- they must! view["ptr_record"] = True return is_buddycloud_enabled(view) if not conn_address in situation: situation[conn_address] = make_output_builder( view, not_buddycloud_enabled) finally: xmpp.disconnect() try: resolver = dns.resolver.Resolver() nameserver = getAuthoritativeNameserver(domain_url) resolver.nameservers = [nameserver] resolver.lifetime = 5 PTR_name = "_buddycloud-server._tcp." + domain_url answer = resolver.query(PTR_name, dns.rdatatype.PTR) except (NXDOMAIN, NoAnswer, Timeout): pass except Exception: pass else: view["ptr_record"] = True #view["channel_server"] = answer return is_buddycloud_enabled(view) if (len(situation) == 1): return situation[situation.keys()[0]]() view["xmpp_servers"] = [] status = 2 for xmpp_server in situation: output = situation[xmpp_server]() if (output[0] == 1): status = 1 view["xmpp_servers"].append({ "name": "%s through port %s" % (xmpp_server), "error": output[2] }) view["status"] = status return multiple_problems(view)