def session(self): """Get an instance of ``requests.Session``. By default, the session will not use certificate verification. To enable certificate verification: - set ``CN_COUCHBASE_VERIFY`` environment variable to ``true`` (default to ``false``) - ensure ``CN_COUCHBASE_CERT_FILE`` pointed to valid Couchbase cluster certificate (default to ``/etc/certs/couchbase.crt``) - optionally, set ``CN_COUCHBASE_HOST_HEADER`` to match Common Name or any of SubjectAltName defined in certificate (default to ``localhost``) """ suppress_verification_warning() if not self._session: self._session = requests.Session() self._session.verify = False verify = as_boolean(os.environ.get("CN_COUCHBASE_VERIFY", False)) if verify: self._session.mount("https://", HostHeaderSSLAdapter()) self._session.verify = os.environ.get("CN_COUCHBASE_CERT_FILE") or "/etc/certs/couchbase.crt" self._session.headers["Host"] = os.environ.get("CN_COUCHBASE_HOST_HEADER") or "localhost" return self._session
def https(q, where, timeout=None, port=443, af=None, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, session=None, path='/dns-query', post=True, bootstrap_address=None, verify=True): """Return the response obtained after sending a query via DNS-over-HTTPS. *q*, a ``dns.message.Message``, the query to send. *where*, a ``str``, the nameserver IP address or the full URL. If an IP address is given, the URL will be constructed using the following schema: https://<IP-address>:<port>/<path>. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, a ``int``, the port to send the query to. The default is 443. *af*, an ``int``, the address family to use. The default is ``None``, which causes the address family to use to be inferred from the form of *where*, or uses the system default. Setting this to AF_INET or AF_INET6 currently has no effect. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *session*, a ``requests.session.Session``. If provided, the session to use to send the queries. *path*, a ``str``. If *where* is an IP address, then *path* will be used to construct the URL to send the DNS query to. *post*, a ``bool``. If ``True``, the default, POST method will be used. *bootstrap_address*, a ``str``, the IP address to use to bypass the system's DNS resolver. *verify*, a ``str`, containing a path to a certificate file or directory. Returns a ``dns.message.Message``. """ wire = q.to_wire() (af, destination, source) = _destination_and_source(af, where, port, source, source_port, False) transport_adapter = None headers = {"accept": "application/dns-message"} try: _ = ipaddress.ip_address(where) url = 'https://{}:{}{}'.format(where, port, path) except ValueError: if bootstrap_address is not None: split_url = urllib.parse.urlsplit(where) headers['Host'] = split_url.hostname url = where.replace(split_url.hostname, bootstrap_address) transport_adapter = HostHeaderSSLAdapter() else: url = where if source is not None: # set source port and source address transport_adapter = SourceAddressAdapter(source) if session: close_session = False else: session = requests.sessions.Session() close_session = True try: if transport_adapter: session.mount(url, transport_adapter) # see https://tools.ietf.org/html/rfc8484#section-4.1.1 for DoH # GET and POST examples if post: headers.update({ "content-type": "application/dns-message", "content-length": str(len(wire)) }) response = session.post(url, headers=headers, data=wire, stream=True, timeout=timeout, verify=verify) else: wire = base64.urlsafe_b64encode(wire).decode('utf-8').strip("=") url += "?dns={}".format(wire) response = session.get(url, headers=headers, stream=True, timeout=timeout, verify=verify) finally: if close_session: session.close() # see https://tools.ietf.org/html/rfc8484#section-4.2.1 for info about DoH # status codes if response.status_code < 200 or response.status_code > 299: raise ValueError('{} responded with status code {}' '\nResponse body: {}'.format(where, response.status_code, response.content)) r = dns.message.from_wire(response.content, keyring=q.keyring, request_mac=q.request_mac, one_rr_per_rrset=one_rr_per_rrset, ignore_trailing=ignore_trailing) r.time = response.elapsed if not q.is_response(r): raise BadResponse return r
def https(q, where, timeout=None, port=443, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, session=None, path='/dns-query', post=True, bootstrap_address=None, verify=True): """Return the response obtained after sending a query via DNS-over-HTTPS. *q*, a ``dns.message.Message``, the query to send. *where*, a ``str``, the nameserver IP address or the full URL. If an IP address is given, the URL will be constructed using the following schema: https://<IP-address>:<port>/<path>. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, a ``int``, the port to send the query to. The default is 443. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *session*, an ``httpx.Client`` or ``requests.session.Session``. If provided, the client/session to use to send the queries. *path*, a ``str``. If *where* is an IP address, then *path* will be used to construct the URL to send the DNS query to. *post*, a ``bool``. If ``True``, the default, POST method will be used. *bootstrap_address*, a ``str``, the IP address to use to bypass the system's DNS resolver. *verify*, a ``str``, containing a path to a certificate file or directory. Returns a ``dns.message.Message``. """ if not have_doh: raise NoDOH('Neither httpx nor requests is available.') # pragma: no cover _httpx_ok = _have_httpx wire = q.to_wire() (af, _, source) = _destination_and_source(where, port, source, source_port, False) transport_adapter = None transport = None headers = { "accept": "application/dns-message" } if af is not None: if af == socket.AF_INET: url = 'https://{}:{}{}'.format(where, port, path) elif af == socket.AF_INET6: url = 'https://[{}]:{}{}'.format(where, port, path) elif bootstrap_address is not None: _httpx_ok = False split_url = urllib.parse.urlsplit(where) headers['Host'] = split_url.hostname url = where.replace(split_url.hostname, bootstrap_address) if _have_requests: transport_adapter = HostHeaderSSLAdapter() else: url = where if source is not None: # set source port and source address if _have_httpx: if source_port == 0: transport = httpx.HTTPTransport(local_address=source[0]) else: _httpx_ok = False if _have_requests: transport_adapter = SourceAddressAdapter(source) if session: if _have_httpx: _is_httpx = isinstance(session, httpx.Client) else: _is_httpx = False if _is_httpx and not _httpx_ok: raise NoDOH('Session is httpx, but httpx cannot be used for ' 'the requested operation.') else: _is_httpx = _httpx_ok if not _httpx_ok and not _have_requests: raise NoDOH('Cannot use httpx for this operation, and ' 'requests is not available.') with contextlib.ExitStack() as stack: if not session: if _is_httpx: session = stack.enter_context(httpx.Client(http1=True, http2=_have_http2, verify=verify, transport=transport)) else: session = stack.enter_context(requests.sessions.Session()) if transport_adapter: session.mount(url, transport_adapter) # see https://tools.ietf.org/html/rfc8484#section-4.1.1 for DoH # GET and POST examples if post: headers.update({ "content-type": "application/dns-message", "content-length": str(len(wire)) }) if _is_httpx: response = session.post(url, headers=headers, content=wire, timeout=timeout) else: response = session.post(url, headers=headers, data=wire, timeout=timeout, verify=verify) else: wire = base64.urlsafe_b64encode(wire).rstrip(b"=") if _is_httpx: wire = wire.decode() # httpx does a repr() if we give it bytes response = session.get(url, headers=headers, timeout=timeout, params={"dns": wire}) else: response = session.get(url, headers=headers, timeout=timeout, verify=verify, params={"dns": wire}) # see https://tools.ietf.org/html/rfc8484#section-4.2.1 for info about DoH # status codes if response.status_code < 200 or response.status_code > 299: raise ValueError('{} responded with status code {}' '\nResponse body: {}'.format(where, response.status_code, response.content)) r = dns.message.from_wire(response.content, keyring=q.keyring, request_mac=q.request_mac, one_rr_per_rrset=one_rr_per_rrset, ignore_trailing=ignore_trailing) r.time = response.elapsed if not q.is_response(r): raise BadResponse return r
def create_session(): session = requests.Session() session.mount("https://", HostHeaderSSLAdapter()) session.headers.update({"Host": "alpha"}) session.verify = cert_file return session
username = os.environ.get("WAPI_USERNAME") password = os.environ.get("WAPI_PASSWORD") domain = os.environ.get("WEDOS_DOMAIN") # poskládám autntizační token podle kuchařky od Wedosu auththingy = sha1() auththingy.update(username.encode("ascii")) auththingy.update( sha1(password.encode("ascii")).hexdigest().encode("ascii")) auththingy.update(str(datetime.now().hour).encode("ascii")) auth_token = auththingy.hexdigest() # Tvorba sezení pro requests s oním SSL adaptérem umožňujícím funkčnost SSL i při adresování pomocí IP s = Session() s.mount('https://', HostHeaderSSLAdapter()) s.headers = {"host": "api.wedos.com"} response = simple_request(s, username, auth_token, domain, "dns-rows-list") rows = response.json()["response"]["data"]["row"] # Tady se prochází záznamy a kouká se který měnit # V if řádku je filtrování podle jména a typu záznamu # Pod tím se pak volá funkce co sestrojí požadavek pro úpravu. Zajímavá proměnná je actual_ip for row in rows: if row["name"] == "" and row["rdtype"] == "A": change_row(s, username, auth_token, row["ID"], actual_ip, domain) if row["name"] == "*" and row["rdtype"] == "A": change_row(s, username, auth_token, row["ID"], actual_ip, domain)