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 classifyDomainByRecord(domain): resolver = dns.resolver.Resolver() resolver.lifetime = 5 try: nameserver = getAuthoritativeNameserver(domain) if nameserver: resolver.nameservers = [nameserver] addresses = resolver.query(domain, dns.rdatatype.CNAME) return {"type": "CNAME", "domain": domain, "addresses": addresses} except dns.resolver.NXDOMAIN: pass except dns.resolver.NoAnswer: pass except Exception as e: return {"type": "PROBLEM", "name": "CNAME record", "value": str(e)} try: addresses = resolver.query(domain, dns.rdatatype.A) return {"type": "A", "domain": domain, "addresses": addresses} except (NXDOMAIN, NoAnswer): return {"type": "NONEXISTENT", "domain": domain, "addresses": []} except Exception as e: return {"type": "PROBLEM", "name": "A record", "value": str(e)}
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 classifyDomainByRecord(domain): resolver = dns.resolver.Resolver() resolver.lifetime = 5 try: resolver.nameservers = [ getAuthoritativeNameserver(domain) ] addresses = resolver.query(domain, dns.rdatatype.CNAME) return { 'type' : 'CNAME', 'domain' : domain, 'addresses' : addresses } except dns.resolver.NXDOMAIN: pass except dns.resolver.NoAnswer: pass except Exception as e: return { 'type' : 'PROBLEM', 'name' : 'CNAME record', 'value' : str(e) } try: addresses = resolver.query(domain, dns.rdatatype.A) return { 'type' : 'A', 'domain' : domain, 'addresses' : addresses } except (NXDOMAIN, NoAnswer): return { 'type' : 'NONEXISTENT', 'domain' : domain, 'addresses' : [] } except Exception as e: return { 'type' : 'PROBLEM', 'name' : 'A record', 'value' : str(e) }
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): 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)