Esempio n. 1
0
    def _url_query(self, api_path, authenticate=True):  # NOQA
        i = 0
        while i <= self.retry_limit:
            i += 1
            try:
                query_url = self._server_url + api_path
                req = Request(query_url)
                starttime = datetime.utcnow()
                if self.wif and authenticate:
                    headers = storjcore.auth.create_headers(
                        self.btctxstore, self._get_server_address(), self.wif)
                    req.add_header("Date", headers["Date"])
                    req.add_header("Authorization", headers["Authorization"])
                logger.info("Query: {0} generated in {1}".format(
                    query_url,
                    datetime.utcnow() - starttime))
                response = urlopen(req, timeout=30)
                if 200 <= response.code <= 299:
                    return response.read()
            except HTTPError as e:
                if e.code == 409:
                    raise exceptions.AddressAlreadyRegistered(
                        self.get_nodeid(), self._server_url)
                elif e.code == 404:
                    raise exceptions.ServerNotFound(self._server_url +
                                                    api_path)
                elif e.code == 400:
                    raise exceptions.InvalidAddress(self.get_nodeid())
                elif e.code == 401:  # auth error (likely clock off)
                    # log "HTTP Error 401: UNAUTHORIZED"
                    logger.warning(logmessages.InvalidAuthenticationHeaders())
                elif e.code == 500:  # pragma: no cover
                    raise exceptions.ServerError(self._server_url)
                else:
                    raise e  # pragma: no cover
            except http.client.HTTPException as e:
                logger.warning(repr(e))
            except URLError as e:
                logger.warning(repr(e))
            except socket.error as e:
                logger.warning(repr(e))

            # retry
            delay = self.retry_delay
            logger.info("Query retry in {0} seconds.".format(delay))
            time.sleep(delay)

        # retry limit
        logger.error("Failed to connect to {0}".format(self._server_url))
        raise exceptions.ConnectionError(self._server_url)
Esempio n. 2
0
    def _url_query(self, api_path, authenticate=True):
        i = 0
        while i <= self.retry_limit:
            i += 1
            try:
                query_url = self._server_url + api_path
                req = Request(query_url)
                if self.wif and authenticate:
                    headers = storjcore.auth.create_headers(
                        self.btctxstore, self._get_server_address(), self.wif
                    )
                    req.add_header("Date", headers["Date"])
                    req.add_header("Authorization", headers["Authorization"])
                logger.info("Query: {0}".format(query_url))
                response = urlopen(req, timeout=30)
                if 200 <= response.code <= 299:
                    return response.read()
            except HTTPError as e:
                #logger.warning(repr(e)) duplicate log entry
                if e.code == 409:
                    raise exceptions.AddressAlreadyRegistered(self.auth_address(),
                                                              self._server_url)
                elif e.code == 404:
                    raise exceptions.ServerNotFound(self._server_url)
                elif e.code == 400:
                    raise exceptions.InvalidAddress(self.auth_address())
                elif e.code == 401:  # auth error (likely clock off)
                    logger.warning(logmessages.InvalidAuthenticationHeaders()) #log "HTTP Error 401: UNAUTHORIZED"
                elif e.code == 500:  # pragma: no cover
                    raise exceptions.ServerError(self._server_url)
                else:
                    raise e  # pragma: no cover
            except http.client.HTTPException as e:
                logger.warning(repr(e))
            except URLError as e:
                logger.warning(repr(e))
            except socket.error as e:
                logger.warning(repr(e))

            # retry
            delay = self.retry_delay
            logger.info("Query retry in {0} seconds.".format(delay))
            time.sleep(delay)

        # retry limit
        logger.error("Failed to connect to {0}".format(self._server_url))
        raise exceptions.ConnectionError(self._server_url)
def download_file(url):
    # Create request structure
    LOG.debug('Trying to download: {}'.format(url))
    try:
        req = Request(url)
    except ValueError as e:
        fatal('Client error. Could not download %r as the URL is invalid. Error: %r' % (url, str(e)))
    req.add_header('User-Agent', 'ARM Update Client/%s)' % uc_version)

    # Read and return
    try:
        r = urlopen(req)
        content = r.read()
        r.close()
        return content
    except URLError as e:
        fatal('Could not download %r. Client error: %r' % (url, str(e)))
    except HTTPError as e:
        fatal('Could not download %r. Server error: %r' % (url, str(e)))
Esempio n. 4
0
    def handle_POST(self):
        """
        Install a remote application in response to an HTTP POST.
        """
        self.verifyAllowRemote()
        parts = len(self.pathParts)
        if parts == self.BASE_DEPTH + 2:
            default_version = True
        elif parts == self.BASE_DEPTH + 3:
            default_version = False
        else:
            raise splunk.BadRequest
        if HTTP_AUTH_TOKEN not in self.args:
            raise splunk.BadRequest("Missing argument: %s" % HTTP_AUTH_TOKEN)
        if HTTP_ACTION not in self.args:
            raise splunk.BadRequest("Missing argument: %s" % HTTP_ACTION)
        if self.args[HTTP_ACTION] not in (HTTP_ACTION_INSTALL,
                                          HTTP_ACTION_DOWNLOAD):
            raise splunk.BadRequest("Invalid value '%s' for argument '%s'" %
                                    (self.args[HTTP_ACTION], HTTP_ACTION))
        # check if this is a cloud stack
        if isCloud(self.sessionKey):
            app_name = self.pathParts[self.BASE_DEPTH + 1]
            # Get all cloud apps and see if the app being installed is vetted for cloud
            # i.e install_method == simple
            # TODO: Change to just querying for the app in question when BASE-4074
            # is finished.
            getargs = {'offset': 0, 'limit': 100}
            vetted_apps = []
            while 1:
                serverResponse, serverContent = splunk.rest.simpleRequest(
                    VETTED_APPS_URI, self.sessionKey, getargs)
                if serverResponse.status != 200:
                    raise splunk.BadRequest(
                        'Error while querying Splunkbase. Splunkd returned %s'
                        % serverContent)
                vetted_app_data = json.loads(serverContent)
                if not vetted_app_data['results']:
                    break
                else:
                    getargs['offset'] += 100
                    vetted_apps.extend(vetted_app_data['results'])
            for app in vetted_apps:
                if app['appid'] == app_name and app[
                        'install_method'] == VETTED_APP_INSTALL_METHOD:
                    break
            else:
                raise splunk.BadRequest(
                    'App %s is not vetted for Splunk Cloud.' % app_name)

        url = self._native_to_foreign_url()
        root = self._get_feed_root(url)
        if default_version:
            root = self._get_latest_version(root)
        href = self._parse_link(root)

        try:
            # Package up a Request with auth information.
            req = Request(href)
            # XXX: Converting the auth token from a POST arg to a header
            # requires us to unquote() it. If the client did not correctly
            # quote() the token, login will fail.
            req.add_header(HTTP_AUTH_HEADER,
                           unquote(self.args[HTTP_AUTH_TOKEN]))
            # Install using this Request object.
            installer = bundle_paths.BundleInstaller()
            if self.args[HTTP_ACTION] == HTTP_ACTION_INSTALL:
                b, status = installer.install_from_url(req,
                                                       sslpol=self._sslpol)
                self.response.setStatus(status)
                if ((status == bundle_paths.BundleInstaller.STATUS_INSTALLED)
                        or
                    (status == bundle_paths.BundleInstaller.STATUS_UPGRADED)):
                    # Migrate old-style bundles.
                    logger.debug("Configuring application contents")
                    try:
                        b.migrate()
                    except Exception as e:
                        logger.exception(e)
                        self.addMessage("WARN",
                                        "Error during configuration: %s" % e)
                    # Redirect to local application.
                    self.response.setHeader("Location",
                                            self._redirect_to_local(b))
                    # Let splunkd know about newly-installed app.
                    logger.debug(
                        "Notifying splunkd that app has been installed")
                    splunk.rest.simpleRequest('apps/local/_reload',
                                              sessionKey=self.sessionKey)
                if status == bundle_paths.BundleInstaller.STATUS_INSTALLED:
                    self.addMessage("INFO",
                                    "Installed application: %s" % b.name())
                elif status == bundle_paths.BundleInstaller.STATUS_UPGRADED:
                    self.addMessage("INFO",
                                    "Upgraded application: %s" % b.name())
                else:
                    self.addMessage(
                        "WARN", "Could not install application: %s" % b.name())
            else:
                assert self.args[HTTP_ACTION] == HTTP_ACTION_DOWNLOAD
                downloaded = installer.download_from_url(req,
                                                         sslpol=self._sslpol)
                self.addMessage("INFO",
                                "Downloaded application file: %s" % downloaded)
                self.response.setHeader('content-type', 'application/json')
                response_json = {"downloaded": downloaded}
                self.response.write(json.dumps(response_json))

        except splunk.ResourceNotFound:
            raise
        except splunk.AuthorizationFailed:
            raise
        except splunk.InternalServerError:
            raise
        except Exception as e:
            logger.exception(e)
            raise splunk.InternalServerError(e)
Esempio n. 5
0
    def forward_port(self, proto, src_port, dest_ip, dest_port=None):
        """
        Creates a new mapping for the default gateway to forward ports.
        Source port is from the perspective of the original client.
        For example, if a client tries to connect to us on port 80,
        the source port is port 80. The destination port isn't
        necessarily 80, however. We might wish to run our web server
        on a different port so we can have the router forward requests
        for port 80 to another port (what I call the destination port.)

        If the destination port isn't specified, it defaults to the
        source port. Proto is either TCP or UDP. Function returns None
        on success, otherwise it raises an exception.
        """

        proto = proto.upper()
        valid_protos = ["TCP", "UDP"]
        if proto not in valid_protos:
            raise Exception("Invalid protocol for forwarding.")

        valid_ports = range(1, 65535)
        if src_port not in valid_ports:
            raise Exception("Invalid port for forwarding.")

        # Source port is forwarded to same destination port number.
        if dest_port is None:
            dest_port = src_port

        # Use UPnP binary for forwarding on Windows.
        if platform.system() == "Windows":
            cmd = "upnpc-static.exe -a %s %s %s %s" % (get_lan_ip(),
                                                       str(src_port),
                                                       str(dest_port),
                                                       proto)
            out, err = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE).communicate()
            if "is not recognized" in err:
                raise Exception("Missing upnpc-static.exe")
            
            return

        # Find gateway address.
        gateway_addr = self.find_gateway()
        if gateway_addr is None:
            raise Exception("Unable to find UPnP compatible gateway.")

        # Get control URL.
        rhost = re.findall('([^/]+)', gateway_addr)
        res = urlopen(gateway_addr, timeout=self.timeout).read().decode("utf-8")
        res = res.replace('\r', '')
        res = res.replace('\n', '')
        res = res.replace('\t', '')
        pres = res.split('<serviceId>urn:upnp-org:serviceId:WANIPConn1'
                         '</serviceId>')
        p2res = pres[1].split('</controlURL>')
        p3res = p2res[0].split('<controlURL>')
        ctrl = p3res[1]
        rip = res.split('<presentationURL>')
        rip1 = rip[1].split('</presentationURL>')
        router_ip = rip1[0]

        port_map_desc = "PyP2P"
        msg = \
            '<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>' \
            + str(src_port) \
            + '</NewExternalPort><NewProtocol>' + str(proto) + '</NewProtocol><NewInternalPort>' \
            + str(dest_port) + '</NewInternalPort><NewInternalClient>' + str(dest_ip) \
            + '</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>' + str(port_map_desc) + '</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>'

        # Attempt to add new port map.
        x = 'http://' + rhost[1] + '/' + ctrl
        if sys.version_info >= (3, 0, 0):
            msg = bytes(msg, "utf-8")

        req = Request('http://' + rhost[1] + '/' + ctrl, msg)
        req.add_header('SOAPAction',
                       '"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"'
                       )
        req.add_header('Content-type', 'application/xml')
        res = urlopen(req, timeout=self.timeout)
Esempio n. 6
0
    def forward_port(self, proto, src_port, dest_ip, dest_port=None):
        """
        Creates a new mapping for the default gateway to forward ports.
        Source port is from the perspective of the original client.
        For example, if a client tries to connect to us on port 80,
        the source port is port 80. The destination port isn't
        necessarily 80, however. We might wish to run our web server
        on a different port so we can have the router forward requests
        for port 80 to another port (what I call the destination port.)

        If the destination port isn't specified, it defaults to the
        source port. Proto is either TCP or UDP. Function returns None
        on success, otherwise it raises an exception.
        """

        proto = proto.upper()
        valid_protos = ["TCP", "UDP"]
        if proto not in valid_protos:
            raise Exception("Invalid protocol for forwarding.")

        valid_ports = range(1, 65535)
        if src_port not in valid_ports:
            raise Exception("Invalid port for forwarding.")

        # Source port is forwarded to same destination port number.
        if dest_port is None:
            dest_port = src_port

        # Use UPnP binary for forwarding on Windows.
        if platform.system() == "Windows":
            cmd = "upnpc-static.exe -a %s %s %s %s" % (
                get_lan_ip(), str(src_port), str(dest_port), proto)
            out, err = subprocess.Popen(cmd,
                                        shell=True,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE).communicate()
            if "is not recognized" in err:
                raise Exception("Missing upnpc-static.exe")

            return

        # Find gateway address.
        gateway_addr = self.find_gateway()
        if gateway_addr is None:
            raise Exception("Unable to find UPnP compatible gateway.")

        # Get control URL.
        rhost = re.findall('([^/]+)', gateway_addr)
        res = urlopen(gateway_addr,
                      timeout=self.timeout).read().decode("utf-8")
        res = res.replace('\r', '')
        res = res.replace('\n', '')
        res = res.replace('\t', '')
        pres = res.split('<serviceId>urn:upnp-org:serviceId:WANIPConn1'
                         '</serviceId>')
        p2res = pres[1].split('</controlURL>')
        p3res = p2res[0].split('<controlURL>')
        ctrl = p3res[1]
        rip = res.split('<presentationURL>')
        rip1 = rip[1].split('</presentationURL>')
        router_ip = rip1[0]

        port_map_desc = "PyP2P"
        msg = \
            '<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>' \
            + str(src_port) \
            + '</NewExternalPort><NewProtocol>' + str(proto) + '</NewProtocol><NewInternalPort>' \
            + str(dest_port) + '</NewInternalPort><NewInternalClient>' + str(dest_ip) \
            + '</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>' + str(port_map_desc) + '</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>'

        # Attempt to add new port map.
        x = 'http://' + rhost[1] + '/' + ctrl
        if sys.version_info >= (3, 0, 0):
            msg = bytes(msg, "utf-8")

        req = Request('http://' + rhost[1] + '/' + ctrl, msg)
        req.add_header(
            'SOAPAction',
            '"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"')
        req.add_header('Content-type', 'application/xml')
        res = urlopen(req, timeout=self.timeout)