Ejemplo n.º 1
0
    def set_cached_token(self, token):
        """ Caches current token in the auth cache.
        """
        log_debug(3)
        # Try to connect to the token-cache.
        shelf = get_auth_shelf()
        # Cache the token.
        try:
            shelf[self.__cache_proxy_key()] = token
        except:
            text = _("""\
Caching of authentication token for proxy id %s failed!
Either the authentication caching daemon is experiencing
problems, isn't running, or the token is somehow corrupt.
""") % self.__serverid
            Traceback("ProxyAuth.set_cached_token", extra=text)
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (auth caching issue). "
                  "Please contact your system administrator.")
            ), None, sys.exc_info()[2]
        log_debug(4, "successfully returning")
        return token
Ejemplo n.º 2
0
    def process_extra_data(self,
                           server_id,
                           action_id,
                           data={},
                           action_type=None):
        log_debug(4, server_id, action_id, action_type)

        if not action_type:
            # Shouldn't happen
            return

        try:
            method = getMethod.getMethod(action_type,
                                         'server.action_extra_data')
        except getMethod.GetMethodException:
            Traceback("queue.get V2")
            raise_with_tb(
                EmptyAction("Could not get a valid method for %s" %
                            action_type),
                sys.exc_info()[2])
        # Call the method
        result = method(self.server_id, action_id, data=data)
        return result
Ejemplo n.º 3
0
    def _handler(self, req):
        log_debug(3, "Method", req.method)

        # Read all the request
        data = req.read()
        log_debug(7, "Received", data)

        # Decode the data
        try:
            params, methodname = xmlrpclib.loads(data)
        except:
            raise

        log_debug(5, params, methodname)

        try:
            f = self.get_function(methodname, req)
        except FunctionRetrievalError:
            e = sys.exc_info()[1]
            Traceback(methodname, req)
            return self._send_xmlrpc(req, rhnFault(3008, str(e), explain=0))

        if len(params) < 2:
            params = []
        else:
            params = params[1:]

        result = f(*params)

        if result:
            # Error of some sort
            return self._send_xmlrpc(req, rhnFault(3009))

        # Presumably the function did all the sending
        log_debug(4, "Exiting OK")
        return apache.OK
Ejemplo n.º 4
0
             # rather big problem: http proxy not running.
             log_error("*** ERROR ***: %s" % error[1])
             Traceback(mail=0)
         except socket.sslerror, e:
             error = ['socket.sslerror',
                      '(%s) %s' % (CFG.HTTP_PROXY, e)]
             # rather big problem: http proxy not running.
             log_error("*** ERROR ***: %s" % error[1])
             Traceback(mail=0)
         else:
             error = ['socket', str(e)]
             log_error(error)
             Traceback(mail=0)
     else:
         log_error("Socket error", e)
         Traceback(mail=0)
     Traceback(mail=1)
     token = None
     time.sleep(.25)
     continue
 except SSL.SSL.Error, e:
     token = None
     error = ['rhn.SSL.SSL.Error', repr(e), str(e)]
     log_error(error)
     Traceback(mail=0)
     time.sleep(.25)
     continue
 except xmlrpclib.ProtocolError, e:
     token = None
     log_error('xmlrpclib.ProtocolError', e)
     time.sleep(.25)
Ejemplo n.º 5
0
class RedirectHandler(SharedHandler):
    """ Spacewalk Proxy SSL Redirect specific handler code called by rhnApache.

        Workflow is:
        Client -> Apache:Broker -> Squid -> Apache:Redirect -> Satellite

        Redirect handler get all request for localhost:80 and they come
        from Broker handler through Squid, which hadle caching.
        Redirect module transform destination url to parent or http proxy.
        Depend on what we have in CFG.
    """
    def __init__(self, req):
        SharedHandler.__init__(self, req)
        self.componentType = 'proxy.redirect'
        self._initConnectionVariables(req)
        self.rhnParentXMLRPC = None

    def _initConnectionVariables(self, _req):
        """ set connection variables
            NOTE: self.{caChain,rhnParent,httpProxy*} are initialized
                  in SharedHandler
        """

        effectiveURI = self._getEffectiveURI()
        effectiveURI_parts = urlparse(effectiveURI)
        scheme = 'http'
        if CFG.USE_SSL:
            scheme = 'https'
        else:
            self.caChain = ''
        self.rhnParentXMLRPC = urlunparse(
            (scheme, self.rhnParent, '/XMLRPC', '', '', ''))
        self.rhnParent = urlunparse((scheme, self.rhnParent) +
                                    effectiveURI_parts[2:])

        log_debug(3, 'remapped self.rhnParent:       %s' % self.rhnParent)
        log_debug(3,
                  'remapped self.rhnParentXMLRPC: %s' % self.rhnParentXMLRPC)

    def handler(self):
        """ Main handler for all requests pumped through this server. """

        log_debug(4, 'In redirect handler')
        self._prepHandler()

        # Rebuild the X-Forwarded-For header so that it reflects the actual
        # path of the request.  We must do this because squid is unable to
        # determine the "real" client, and will make each entry in the chain
        # 127.0.0.1.
        _oto = rhnFlags.get('outputTransportOptions')
        _oto['X-Forwarded-For'] = _oto['X-RHN-IP-Path']

        self.rhnParent = self.rhnParent or ''  # paranoid

        log_debug(4, 'Connecting to parent...')
        self._connectToParent()  # part 1

        log_debug(4, 'Initiating communication with server...')
        status = self._serverCommo()  # part 2
        if (status != apache.OK) and (status != apache.HTTP_PARTIAL_CONTENT):
            log_debug(3, "Leaving handler with status code %s" % status)
            return status

        log_debug(4, 'Initiating communication with client...')
        # If we got this far, it has to be a good response
        return self._clientCommo(status)

    def _handleServerResponse(self, status):
        """ Here, we'll override the default behavior for handling server responses
            so that we can adequately handle 302's.

            We will follow redirects unless it is redirect to (re)login page. In which
            case we change protocol to https and return redirect to user.
        """

        # In case of a 302, redirect the original request to the location
        # specified in the response.

        if status == apache.HTTP_MOVED_TEMPORARILY or \
           status == apache.HTTP_MOVED_PERMANENTLY:

            log_debug(1, "Received redirect response: ", status)

            # if we redirected to ssl version of login page, send redirect directly to user
            headers = self.responseContext.getHeaders()
            if headers is not None:
                for headerKey in headers.keys():
                    if headerKey == 'location':
                        location = self._get_header(headerKey)
                        relogin = re.compile(
                            r'https?://.*(/rhn/(Re)?Login.do\?.*)')
                        m = relogin.match(location[0])
                        if m:
                            # pull server name out of "t:o:k:e:n:hostname1,t:o:k:e:n:hostname2,..."
                            proxy_auth = self.req.headers_in[
                                'X-RHN-Proxy-Auth']
                            last_auth = proxy_auth.split(',')[-1]
                            server_name = last_auth.split(':')[-1]
                            log_debug(
                                1, "Redirecting to SSL version of login page")
                            rhnLib.setHeaderValue(
                                self.req.headers_out, 'Location',
                                "https://%s%s" % (server_name, m.group(1)))
                            return apache.HTTP_MOVED_PERMANENTLY

            redirectStatus = self.__redirectToNextLocation()

            # At this point, we've either:
            #
            #     (a) successfully redirected to the 3rd party
            #     (b) been told to redirect somewhere else from the 3rd party
            #     (c) run out of retry attempts
            #
            # We'll keep redirecting until we've received HTTP_OK or an error.

            while redirectStatus == apache.HTTP_MOVED_PERMANENTLY or \
                  redirectStatus == apache.HTTP_MOVED_TEMPORARILY:

                # We've been told to redirect again.  We'll pass a special
                # argument to ensure that if we end up back at the server, we
                # won't be redirected again.

                log_debug(1, "Redirected again!  Code=", redirectStatus)
                redirectStatus = self.__redirectToNextLocation(True)

            if (redirectStatus != apache.HTTP_OK) and (
                    redirectStatus != apache.HTTP_PARTIAL_CONTENT):

                # We must have run out of retry attempts.  Fail over to Hosted
                # to perform the request.

                log_debug(1, "Redirection failed; retries exhausted.  " \
                             "Failing over.  Code=",                    \
                             redirectStatus)
                redirectStatus = self.__redirectFailover()

            return SharedHandler._handleServerResponse(self, redirectStatus)

        else:
            # Otherwise, revert to default behavior.
            return SharedHandler._handleServerResponse(self, status)

    def __redirectToNextLocation(self, loopProtection=False):
        """ This function will perform a redirection to the next location, as
            specified in the last response's "Location" header. This function will
            return an actual HTTP response status code.  If successful, it will
            return apache.HTTP_OK, not apache.OK.  If unsuccessful, this function
            will retry a configurable number of times, as defined in
            CFG.NETWORK_RETRIES.  The following codes define "success".

              HTTP_OK
              HTTP_PARTIAL_CONTENT
              HTTP_MOVED_TEMPORARILY
              HTTP_MOVED_PERMANENTLY

            Upon successful completion of this function, the responseContext
            should be populated with the response.

            Arguments:

            loopProtection - If True, this function will insert a special
                           header into the new request that tells the RHN
                           server not to issue another redirect to us, in case
                           that's where we end up being redirected.

            Return:

            This function may return any valid HTTP_* response code.  See
            __redirectToNextLocationNoRetry for more info.
        """
        retriesLeft = CFG.NETWORK_RETRIES

        # We'll now try to redirect to the 3rd party.  We will keep
        # retrying until we exhaust the number of allowed attempts.
        # Valid response codes are:
        #     HTTP_OK
        #     HTTP_PARTIAL_CONTENT
        #     HTTP_MOVED_PERMANENTLY
        #     HTTP_MOVED_TEMPORARILY

        redirectStatus = self.__redirectToNextLocationNoRetry(loopProtection)
        while redirectStatus != apache.HTTP_OK                and \
              redirectStatus != apache.HTTP_PARTIAL_CONTENT   and \
              redirectStatus != apache.HTTP_MOVED_PERMANENTLY and \
              redirectStatus != apache.HTTP_MOVED_TEMPORARILY and \
              retriesLeft > 0:

            retriesLeft = retriesLeft - 1
            log_debug(1, "Redirection failed; trying again.  " \
                         "Retries left=",                      \
                         retriesLeft,                          \
                         "Code=",                              \
                         redirectStatus)

            # Pop the current response context and restore the state to
            # the last successful response.  The acts of remove the current
            # context will cause all of its open connections to be closed.
            self.responseContext.remove()

            # XXX: Possibly sleep here for a second?
            redirectStatus = \
                self.__redirectToNextLocationNoRetry(loopProtection)

        return redirectStatus

    def __redirectToNextLocationNoRetry(self, loopProtection=False):
        """ This function will perform a redirection to the next location, as
            specified in the last response's "Location" header. This function will
            return an actual HTTP response status code.  If successful, it will
            return apache.HTTP_OK, not apache.OK.  If unsuccessful, this function
            will simply return; no retries will be performed.  The following error
            codes can be returned:

            HTTP_OK,HTTP_PARTIAL_CONTENT - Redirect successful.
            HTTP_MOVED_TEMPORARILY     - Redirect was redirected again by 3rd party.
            HTTP_MOVED_PERMANENTLY     - Redirect was redirected again by 3rd party.
            HTTP_INTERNAL_SERVER_ERROR - Error extracting redirect information
            HTTP_SERVICE_UNAVAILABLE   - Could not connect to 3rd party server,
                                         connection was reset, or a read error
                                         occurred during communication.
            HTTP_*                     - Any other HTTP status code may also be
                                         returned.

            Upon successful completion of this function, a new responseContext
            will be created and pushed onto the stack.
        """

        # Obtain the redirect location first before we replace the current
        # response context.  It's contained in the Location header of the
        # previous response.

        redirectLocation = self._get_header(rhnConstants.HEADER_LOCATION)

        # We are about to redirect to a new location so now we'll push a new
        # response context before we return any errors.
        self.responseContext.add()

        # There should always be a redirect URL passed back to us.  If not,
        # there's an error.

        if not redirectLocation or len(redirectLocation) == 0:
            log_error("  No redirect location specified!")
            Traceback(mail=0)
            return apache.HTTP_INTERNAL_SERVER_ERROR

        # The _get_header function returns the value as a list.  There should
        # always be exactly one location specified.

        redirectLocation = redirectLocation[0]
        log_debug(1, "  Redirecting to: ", redirectLocation)

        # Tear apart the redirect URL.  We need the scheme, the host, the
        # port (if not the default), and the URI.

        _scheme, host, port, uri = self._parse_url(redirectLocation)

        # Add any params onto the URI since _parse_url doesn't include them.
        if redirectLocation.find('?') > -1:
            uri += redirectLocation[redirectLocation.index('?'):]

        # Now create a new connection.  We'll use SSL if configured to do
        # so.

        params = {
            'host': host,
            'port': port,
        }
        if CFG.has_key('timeout'):
            params['timeout'] = CFG.TIMEOUT
        if CFG.USE_SSL:
            log_debug(1, "  Redirecting with SSL.  Cert= ", self.caChain)
            params['trusted_certs'] = [self.caChain]
            connection = connections.HTTPSConnection(**params)
        else:
            log_debug(1, "  Redirecting withOUT SSL.")
            connection = connections.HTTPConnection(**params)

        # Put the connection into the current response context.
        self.responseContext.setConnection(connection)

        # Now open the connection to the 3rd party server.

        log_debug(4, "Attempting to connect to 3rd party server...")
        try:
            connection.connect()
        except socket.error, e:
            log_error("Error opening redirect connection", redirectLocation, e)
            Traceback(mail=0)
            return apache.HTTP_SERVICE_UNAVAILABLE
        log_debug(4, "Connected to 3rd party server:",
                  connection.sock.getpeername())

        # Put the request out on the wire.

        response = None
        try:
            # We'll redirect to the URI made in the original request, but with
            # the new server instead.

            log_debug(4, "Making request: ", self.req.method, uri)
            connection.putrequest(self.req.method, uri)

            # Add some custom headers.

            if loopProtection:
                connection.putheader(rhnConstants.HEADER_RHN_REDIRECT, '0')

            log_debug(4, "  Adding original URL header: ", self.rhnParent)
            connection.putheader(rhnConstants.HEADER_RHN_ORIG_LOC,
                                 self.rhnParent)

            # Add all the other headers in the original request in case we
            # need to re-authenticate with Hosted.

            for hdr in self.req.headers_in.keys():
                if hdr.lower().startswith("x-rhn"):
                    connection.putheader(hdr, self.req.headers_in[hdr])
                    log_debug(4, "Passing request header: ", hdr,
                              self.req.headers_in[hdr])

            connection.endheaders()

            response = connection.getresponse()
        except IOError, ioe:
            # Raised by getresponse() if server closes connection on us.
            log_error("Redirect connection reset by peer.", redirectLocation,
                      ioe)
            Traceback(mail=0)

            # The connection is saved in the current response context, and
            # will be closed when the caller pops the context.
            return apache.HTTP_SERVICE_UNAVAILABLE
Ejemplo n.º 6
0
    def __redirectToNextLocationNoRetry(self, loopProtection=False):
        """ This function will perform a redirection to the next location, as
            specified in the last response's "Location" header. This function will
            return an actual HTTP response status code.  If successful, it will
            return apache.HTTP_OK, not apache.OK.  If unsuccessful, this function
            will simply return; no retries will be performed.  The following error
            codes can be returned:

            HTTP_OK,HTTP_PARTIAL_CONTENT - Redirect successful.
            HTTP_MOVED_TEMPORARILY     - Redirect was redirected again by 3rd party.
            HTTP_MOVED_PERMANENTLY     - Redirect was redirected again by 3rd party.
            HTTP_INTERNAL_SERVER_ERROR - Error extracting redirect information
            HTTP_SERVICE_UNAVAILABLE   - Could not connect to 3rd party server,
                                         connection was reset, or a read error
                                         occurred during communication.
            HTTP_*                     - Any other HTTP status code may also be
                                         returned.

            Upon successful completion of this function, a new responseContext
            will be created and pushed onto the stack.
        """

        # Obtain the redirect location first before we replace the current
        # response context.  It's contained in the Location header of the
        # previous response.

        redirectLocation = self._get_header(rhnConstants.HEADER_LOCATION)

        # We are about to redirect to a new location so now we'll push a new
        # response context before we return any errors.
        self.responseContext.add()

        # There should always be a redirect URL passed back to us.  If not,
        # there's an error.

        if not redirectLocation or len(redirectLocation) == 0:
            log_error("  No redirect location specified!")
            Traceback(mail=0)
            return apache.HTTP_INTERNAL_SERVER_ERROR

        # The _get_header function returns the value as a list.  There should
        # always be exactly one location specified.

        redirectLocation = redirectLocation[0]
        log_debug(1, "  Redirecting to: ", redirectLocation)

        # Tear apart the redirect URL.  We need the scheme, the host, the
        # port (if not the default), and the URI.

        _scheme, host, port, uri = self._parse_url(redirectLocation)

        # Add any params onto the URI since _parse_url doesn't include them.
        if redirectLocation.find('?') > -1:
            uri += redirectLocation[redirectLocation.index('?'):]

        # Now create a new connection.  We'll use SSL if configured to do
        # so.

        params = {
            'host': host,
            'port': port,
        }
        if CFG.has_key('timeout'):
            params['timeout'] = CFG.TIMEOUT
        if CFG.USE_SSL:
            log_debug(1, "  Redirecting with SSL.  Cert= ", self.caChain)
            params['trusted_certs'] = [self.caChain]
            connection = connections.HTTPSConnection(**params)
        else:
            log_debug(1, "  Redirecting withOUT SSL.")
            connection = connections.HTTPConnection(**params)

        # Put the connection into the current response context.
        self.responseContext.setConnection(connection)

        # Now open the connection to the 3rd party server.

        log_debug(4, "Attempting to connect to 3rd party server...")
        try:
            connection.connect()
        except socket.error, e:
            log_error("Error opening redirect connection", redirectLocation, e)
            Traceback(mail=0)
            return apache.HTTP_SERVICE_UNAVAILABLE
Ejemplo n.º 7
0
    def response(self, req, response):
        """ send the response (common code) """

        # Send the xml-rpc response back
        log_debug(5, "Response type", type(response))

        needs_xmlrpc_encoding = rhnFlags.test("NeedEncoding")
        compress_response = rhnFlags.test("compress_response")
        # Init an output object; we'll use it for sending data in various
        # formats
        if isinstance(response, rpclib.transports.File):
            if not hasattr(response.file_obj, 'fileno') and compress_response:
                # This is a StringIO that has to be compressed, so read it in
                # memory; mark that we don't have to do any xmlrpc encoding
                response = response.file_obj.read()
                needs_xmlrpc_encoding = 0
            else:
                # Just treat is as a file
                return self.response_file(req, response)

        is_fault = 0
        if isinstance(response, rhnFault):
            if req.method == 'GET':
                return self._response_fault_get(req, response.getxml())
            # Need to encode the response as xmlrpc
            response = response.getxml()
            is_fault = 1
            # No compression
            compress_response = 0
            # This is an xmlrpc Fault, so we have to encode it
            needs_xmlrpc_encoding = 1

        output = rpclib.transports.Output()

        if not is_fault:
            # First, use the same encoding/transfer that the client used
            output.set_transport_flags(
                transfer=rpclib.transports.lookupTransfer(self.input.transfer),
                encoding=rpclib.transports.lookupEncoding(self.input.encoding))

        if compress_response:
            # check if we have to compress this result
            log_debug(4, "Compression on for client version",
                      self.clientVersion)
            if self.clientVersion > 0:
                output.set_transport_flags(output.TRANSFER_BINARY,
                                           output.ENCODE_ZLIB)
            else:  # original clients had the binary transport support broken
                output.set_transport_flags(output.TRANSFER_BASE64,
                                           output.ENCODE_ZLIB)

        # We simply add the transport options to the output headers
        output.headers.update(rhnFlags.get('outputTransportOptions').dict())

        if needs_xmlrpc_encoding:
            # Normalize the response
            response = self.normalize(response)
            try:
                response = rpclib.xmlrpclib.dumps(response, methodresponse=1)
            except TypeError, e:
                log_debug(
                    -1, "Error \"%s\" encoding response = %s" % (e, response))
                Traceback("apacheHandler.response",
                          req,
                          extra="Error \"%s\" encoding response = %s" %
                          (e, response),
                          severity="notification")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            except Exception:  # pylint: disable=E0012, W0703
                # Uncaught exception; signal the error
                Traceback("apacheHandler.response", req, severity="unhandled")
                return apache.HTTP_INTERNAL_SERVER_ERROR
Ejemplo n.º 8
0
    def __redirectToNextLocationNoRetry(self, loopProtection=False):
        """ This function will perform a redirection to the next location, as
            specified in the last response's "Location" header. This function will
            return an actual HTTP response status code.  If successful, it will
            return apache.HTTP_OK, not apache.OK.  If unsuccessful, this function
            will simply return; no retries will be performed.  The following error
            codes can be returned:

            HTTP_OK,HTTP_PARTIAL_CONTENT - Redirect successful.
            HTTP_MOVED_TEMPORARILY     - Redirect was redirected again by 3rd party.
            HTTP_MOVED_PERMANENTLY     - Redirect was redirected again by 3rd party.
            HTTP_INTERNAL_SERVER_ERROR - Error extracting redirect information
            HTTP_SERVICE_UNAVAILABLE   - Could not connect to 3rd party server,
                                         connection was reset, or a read error
                                         occurred during communication.
            HTTP_*                     - Any other HTTP status code may also be
                                         returned.

            Upon successful completion of this function, a new responseContext
            will be created and pushed onto the stack.
        """

        # Obtain the redirect location first before we replace the current
        # response context.  It's contained in the Location header of the
        # previous response.

        redirectLocation = self._get_header(rhnConstants.HEADER_LOCATION)

        # We are about to redirect to a new location so now we'll push a new
        # response context before we return any errors.
        self.responseContext.add()

        # There should always be a redirect URL passed back to us.  If not,
        # there's an error.

        if not redirectLocation:
            log_error("  No redirect location specified!")
            Traceback(mail=0)
            return apache.HTTP_INTERNAL_SERVER_ERROR

        # The _get_header function returns the value as a list.  There should
        # always be exactly one location specified.

        redirectLocation = redirectLocation[0]
        log_debug(1, "  Redirecting to: ", redirectLocation)

        # Tear apart the redirect URL.  We need the scheme, the host, the
        # port (if not the default), and the URI.

        _scheme, host, port, uri, query = self._parse_url(redirectLocation)

        # Add back the query string
        if query:
            uri += '?' + query

        # Now create a new connection.  We'll use SSL if configured to do
        # so.

        params = {
            'host': host,
            'port': port,
        }
        if CFG.has_key('timeout'):
            params['timeout'] = CFG.TIMEOUT
        if CFG.USE_SSL:
            log_debug(1, "  Redirecting with SSL.  Cert= ", self.caChain)
            params['trusted_certs'] = [self.caChain]
            connection = connections.HTTPSConnection(**params)
        else:
            log_debug(1, "  Redirecting withOUT SSL.")
            connection = connections.HTTPConnection(**params)

        # Put the connection into the current response context.
        self.responseContext.setConnection(connection)

        # Now open the connection to the 3rd party server.

        log_debug(4, "Attempting to connect to 3rd party server...")
        try:
            connection.connect()
        except socket.error as e:
            log_error("Error opening redirect connection", redirectLocation, e)
            Traceback(mail=0)
            return apache.HTTP_SERVICE_UNAVAILABLE
        log_debug(4, "Connected to 3rd party server:",
                  connection.sock.getpeername())

        # Put the request out on the wire.

        response = None
        try:
            # We'll redirect to the URI made in the original request, but with
            # the new server instead.

            log_debug(4, "Making request: ", self.req.method, uri)
            connection.putrequest(self.req.method, uri)

            # Add some custom headers.

            if loopProtection:
                connection.putheader(rhnConstants.HEADER_RHN_REDIRECT, '0')

            log_debug(4, "  Adding original URL header: ", self.rhnParent)
            connection.putheader(rhnConstants.HEADER_RHN_ORIG_LOC,
                                 self.rhnParent)

            # Add all the other headers in the original request in case we
            # need to re-authenticate with Hosted.

            for hdr in list(self.req.headers_in.keys()):
                if hdr.lower().startswith("x-rhn"):
                    connection.putheader(hdr, self.req.headers_in[hdr])
                    log_debug(4, "Passing request header: ", hdr,
                              self.req.headers_in[hdr])

            connection.endheaders()

            response = connection.getresponse()
        except IOError as ioe:
            # Raised by getresponse() if server closes connection on us.
            log_error("Redirect connection reset by peer.", redirectLocation,
                      ioe)
            Traceback(mail=0)

            # The connection is saved in the current response context, and
            # will be closed when the caller pops the context.
            return apache.HTTP_SERVICE_UNAVAILABLE

        except socket.error as se:
            # Some socket error occurred.  Possibly a read error.
            log_error("Redirect request failed.", redirectLocation, se)
            Traceback(mail=0)

            # The connection is saved in the current response context, and
            # will be closed when the caller pops the context.
            return apache.HTTP_SERVICE_UNAVAILABLE

        # Save the response headers and body FD in the current communication
        # context.

        self.responseContext.setBodyFd(response)
        self.responseContext.setHeaders(response.msg)

        log_debug(4, "Response headers: ",
                  list(self.responseContext.getHeaders().items()))
        log_debug(4, "Got redirect response.  Status=", response.status)

        # Return the HTTP status to the caller.

        return response.status
Ejemplo n.º 9
0
    def call_function(self, method, params):
        # short-circuit everything if sending a system-wide message.
        if CFG.SEND_MESSAGE_TO_ALL:
            # Make sure the applet doesn't see the message
            if method == 'applet.poll_status':
                return self.response({
                    'checkin_interval': 3600,
                    'server_status': 'normal'
                })
            if method == 'applet.poll_packages':
                return self.response({'use_cached_copy': 1})

            # Fetch global message being sent to clients if applicable.
            msg = open(CFG.MESSAGE_TO_ALL).read()
            log_debug(3, "Sending message to all clients: %s" % msg)
            # Send the message as a fault.
            response = xmlrpclib.Fault(
                -1, _("IMPORTANT MESSAGE FOLLOWS:\n%s") % msg)
            # and now send everything back
            ret = self.response(response)
            log_debug(4, "Leave with return value", ret)
            return ret

        # req: where the response is sent to
        log_debug(2, method)

        # Now we have the reference, call away
        force_rollback = 1
        try:
            rhnSQL.clear_log_id()
            # now get the function reference and call it
            func = self.method_ref(method)
            response = func(*params)
        except (TypeError, ValueError, KeyError, IndexError, UnknownXML):
            # report exception back to server
            fault = 1

            if sys.version_info[0] == 3:
                exctype = sys.exc_info()[0]
            else:
                exctype = sys.exc_type

            if exctype == UnknownXML:
                fault = -1
            e_type, e_value = sys.exc_info()[:2]
            response = xmlrpclib.Fault(fault, _(
                "While running '%s': caught\n%s : %s\n") % (
                method, e_type, e_value))
            Traceback(method, self.req,
                      extra="Response sent back to the caller:\n%s\n" % (
                          response.faultString,),
                      severity="notification")
        except rhnNotFound:
            e = sys.exc_info()[1]
            return apache.HTTP_NOT_FOUND
        # pkilambi:catch exception if redirect
        except redirectException:
            re = sys.exc_info()[1]
            log_debug(3, "redirect exception caught", re.path)
            response = re.path

        except rhnFault:
            f = sys.exc_info()[1]
            response = f.getxml()
        except rhnSQL.SQLSchemaError:
            e = sys.exc_info()[1]
            f = None
            if e.errno == 20200:
                log_debug(2, "User Group Membership EXCEEDED")
                f = rhnFault(43, e.errmsg)
            if not f:
                log_error("rhnSQL.SQLSchemaError caught", e)
                rhnSQL.rollback()
                # generate the traceback report
                Traceback(method, self.req,
                          extra="SQL Error generated: %s" % e,
                          severity="schema")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            response = f.getxml()
        except rhnSQL.SQLError:
            e = sys.exc_info()[1]
            log_error("rhnSQL.SQLError caught", e)
            rhnSQL.rollback()
            Traceback(method, self.req,
                      extra="SQL Error generated: %s" % e,
                      severity="schema")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        except Exception:
            e = sys.exc_info()[1]
            log_error("Unhandled exception", e)
            rhnSQL.rollback()
            # otherwise we do a full stop
            Traceback(method, self.req, severity="unhandled")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        else:
            # if no exception, we don't need to rollback
            force_rollback = 0
        if force_rollback:
            rhnSQL.rollback()
        rhnSQL.clear_log_id()
        # and now send everything back
        ret = self.response(response)
        log_debug(4, "Leave with return value", ret)
        return ret
Ejemplo n.º 10
0
 except rhnFault, f:
     response = f.getxml()
 except rhnSQL.SQLSchemaError, e:
     f = None
     if e.errno == 20200:
         log_debug(2, "User Group Membership EXCEEDED")
         f = rhnFault(43, e.errmsg)
     elif e.errno == 20220:
         log_debug(2, "Server Group Membership EXCEEDED")
         f = rhnFault(44, e.errmsg)
     if not f:
         log_error("rhnSQL.SQLSchemaError caught", e)
         rhnSQL.rollback()
         # generate the traceback report
         Traceback(method,
                   self.req,
                   extra="SQL Error generated: %s" % e,
                   severity="schema")
         return apache.HTTP_INTERNAL_SERVER_ERROR
     response = f.getxml()
 except rhnSQL.SQLError, e:
     log_error("rhnSQL.SQLError caught", e)
     rhnSQL.rollback()
     Traceback(method,
               self.req,
               extra="SQL Error generated: %s" % e,
               severity="schema")
     return apache.HTTP_INTERNAL_SERVER_ERROR
 except Exception, e:
     log_error("Unhandled exception", e)
     rhnSQL.rollback()
     # otherwise we do a full stop
Ejemplo n.º 11
0
            error_string = self._exception_to_text(e)
            error_code = e.code
            self._error_to_headers(req.err_headers_out, error_code, error_string)
            ret = rhnFlags.get("apache-return-code")
            if not ret:
                ret = apache.HTTP_INTERNAL_SERVER_ERROR
            req.status = ret
            log_debug(4, "_wrapper %s exited with apache code %s" %
                (function_name, ret))
        except rhnSession.ExpiredSessionError, e:
            #if session expires we catch here and return a forbidden
            #abd make it re-authenticate
            log_debug(4, "Expire Session Error Caught: %s" % (e, ))
            return 403
        except:
            Traceback("server.apacheUploadServer._wrapper", req=req)
            log_error("Unhandled exception")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        return ret

    # Adds an error code and error string to the headers passed in
    def _error_to_headers(self, headers, error_code, error_string):
        error_string = string.strip(error_string)
        import base64
        error_string = string.strip(base64.encodestring(error_string))
        for line in map(string.strip, string.split(error_string, '\n')):
            headers.add(self.server.error_header_prefix + '-String', line)
        headers[self.server.error_header_prefix + '-Code'] = str(error_code)

    def _exception_to_text(self, exception):
        return """\
Ejemplo n.º 12
0
        return apache.OK

    def _cleanupHandler(self, _req):
        return apache.OK

    def _wrapper(self, req, function):
        try:
            ret = function(req)
        except rhnFault, e:
            return self._send_xmlrpc(req, e)
        except ClosedConnectionError:
            # The error code most likely doesn't matter, the client won't see
            # it anyway
            return apache.HTTP_NOT_ACCEPTABLE
        except Exception:  # pylint: disable=E0012, W0703
            Traceback("satexport._wrapper", req=req)
            return apache.HTTP_INTERNAL_SERVER_ERROR
        return ret

    def _send_xmlrpc(self, req, data):
        log_debug(1)
        req.content_type = "text/xml"
        if isinstance(data, rhnFault):
            data = data.getxml()
        else:
            data = (data, )
        ret = xmlrpclib.dumps(data, methodresponse=1)
        req.headers_out['Content-Length'] = str(len(ret))
        req.send_http_header()
        req.write(ret)
        return apache.OK
Ejemplo n.º 13
0
    def response(self, req, response):
        """ send the response (common code) """

        # Send the xml-rpc response back
        log_debug(5, "Response type", type(response))

        needs_xmlrpc_encoding = rhnFlags.test("NeedEncoding")
        compress_response = rhnFlags.test("compress_response")
        # Init an output object; we'll use it for sending data in various
        # formats
        if isinstance(response, rpclib.transports.File):
            if not hasattr(response.file_obj, 'fileno') and compress_response:
                # This is a StringIO that has to be compressed, so read it in
                # memory; mark that we don't have to do any xmlrpc encoding
                response = response.file_obj.read()
                needs_xmlrpc_encoding = 0
            else:
                # Just treat is as a file
                return self.response_file(req, response)

        is_fault = 0
        if isinstance(response, rhnFault):
            if req.method == 'GET':
                return self._response_fault_get(req, response.getxml())
            # Need to encode the response as xmlrpc
            response = response.getxml()
            is_fault = 1
            # No compression
            compress_response = 0
            # This is an xmlrpc Fault, so we have to encode it
            needs_xmlrpc_encoding = 1

        output = rpclib.transports.Output()

        if not is_fault:
            # First, use the same encoding/transfer that the client used
            output.set_transport_flags(
                transfer=rpclib.transports.lookupTransfer(self.input.transfer),
                encoding=rpclib.transports.lookupEncoding(self.input.encoding))

        if compress_response:
            # check if we have to compress this result
            log_debug(4, "Compression on for client version", self.clientVersion)
            if self.clientVersion > 0:
                output.set_transport_flags(output.TRANSFER_BINARY,
                                           output.ENCODE_ZLIB)
            else:  # original clients had the binary transport support broken
                output.set_transport_flags(output.TRANSFER_BASE64,
                                           output.ENCODE_ZLIB)

        # We simply add the transport options to the output headers
        output.headers.update(rhnFlags.get('outputTransportOptions').dict())

        if needs_xmlrpc_encoding:
            # Normalize the response
            response = self.normalize(response)
            try:
                response = rpclib.xmlrpclib.dumps(response, methodresponse=1)
            except TypeError as e:
                log_debug(-1, "Error \"%s\" encoding response = %s" % (e, response))
                Traceback("apacheHandler.response", req,
                          extra="Error \"%s\" encoding response = %s" % (e, response),
                          severity="notification")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            except Exception:  # pylint: disable=E0012, W0703
                # Uncaught exception; signal the error
                Traceback("apacheHandler.response", req,
                          severity="unhandled")
                return apache.HTTP_INTERNAL_SERVER_ERROR

        # we're about done here, patch up the headers
        output.process(response)
        # Copy the rest of the fields
        for k, v in list(output.headers.items()):
            if k.lower() == 'content-type':
                # Content-type
                req.content_type = v
            else:
                setHeaderValue(req.headers_out, k, v)

        if CFG.DEBUG == 4:
            # I wrap this in an "if" so we don't parse a large file for no reason.
            log_debug(4, "The response: %s[...SNIP (for sanity) SNIP...]%s" %
                      (response[:100], response[-100:]))
        elif CFG.DEBUG >= 5:
            # if you absolutely must have that whole response in the log file
            log_debug(5, "The response: %s" % response)

        # send the headers
        req.send_http_header()
        try:
            # XXX: in case data is really large maybe we should split
            # it in smaller chunks instead of blasting everything at
            # once. Not yet a problem...
            req.write(output.data)
        except IOError:
            # send_http_header is already sent, so it doesn't make a lot of
            # sense to return a non-200 error; but there is no better solution
            return apache.HTTP_BAD_REQUEST
        del output
        return apache.OK
Ejemplo n.º 14
0
             Traceback(mail=0)
         except socket.sslerror, e:
             error = [
                 'socket.sslerror',
                 '(%s) %s' % (CFG.HTTP_PROXY, e)
             ]
             # rather big problem: http proxy not running.
             log_error("*** ERROR ***: %s" % error[1])
             Traceback(mail=0)
         else:
             error = ['socket', str(e)]
             log_error(error)
             Traceback(mail=0)
     else:
         log_error("Socket error", e)
         Traceback(mail=0)
     Traceback(mail=1)
     token = None
     time.sleep(.25)
     continue
 except SSL.SSL.Error, e:
     token = None
     error = ['rhn.SSL.SSL.Error', repr(e), str(e)]
     log_error(error)
     Traceback(mail=0)
     time.sleep(.25)
     continue
 except xmlrpclib.ProtocolError, e:
     token = None
     log_error('xmlrpclib.ProtocolError', e)
     time.sleep(.25)
#!/usr/bin/python
#
# Copyright (c) 2008--2013 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public License,
# version 2 (GPLv2). There is NO WARRANTY for this software, express or
# implied, including the implied warranties of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
# along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
#
# Red Hat trademarks are not licensed under GPLv2. No permission is
# granted to use or replicate Red Hat trademarks that are incorporated
# in this software or its documentation.
#
# This test tries to make a connection to a database that doesn't exist.
# It catches the exception and sends the traceback, but the DB password should
# be censored.
# Run the test and look into the email.

from spacewalk.server import rhnSQL
from spacewalk.common.rhnConfig import initCFG
from spacewalk.common.rhnTB import Traceback

initCFG('server.xmlrpc')

try:
    rhnSQL.initDB("rhnuser/rhnuser@webde")
except:
    Traceback('test_censored_db_password', mail=1)
Ejemplo n.º 16
0
    def login(self):
        """ Login and fetch new token (proxy token).

            How it works in a nutshell.
            Only the broker component uses this. We perform a xmlrpc request
            to rhn_parent. This occurs outside of the http process we are
            currently working on. So, we do this all on our own; do all of
            our own SSL decisionmaking etc. We use CFG.RHN_PARENT as we always
            bypass the SSL redirect.

            DESIGN NOTES:  what is the proxy auth token?
            -------------------------------------------
            An Spacewalk Proxy auth token is a token fetched upon login from
            Red Hat Satellite or hosted.

            It has this format:
               'S:U:ST:EO:SIG'
            Where:
               S   = server ID
               U   = username
               ST  = server time
               EO  = expiration offset
               SIG = signature
               H   = hostname (important later)

            Within this function within the Spacewalk Proxy Broker we also tag on
            the hostname to the end of the token. The token as described above
            is enough for authentication purposes, but we need a to identify
            the exact hostname (as the Spacewalk Proxy sees it). So now the token
            becomes (token:hostname):
               'S:U:ST:EO:SIG:H'

            DESIGN NOTES:  what is X-RHN-Proxy-Auth?
            -------------------------------------------
            This is where we use the auth token beyond Spacewalk Proxy login
            purposes. This a header used to track request routes through
            a hierarchy of RHN Proxies.

            X-RHN-Proxy-Auth is a header that passes proxy authentication
            information around in the form of an ordered list of tokens. This
            list is used to gain information as to how a client request is
            routed throughout an RHN topology.

            Format: 'S1:U1:ST1:EO1:SIG1:H1,S2:U2:ST2:EO2:SIG2:H2,...'
                     |_________1_________| |_________2_________| |__...
                             token                 token
                     where token is really: token:hostname

            leftmost token was the first token hit by a client request.
            rightmost token was the last token hit by a client request.

        """
        # pylint: disable=R0915

        log_debug(3)
        server = self.__getXmlrpcServer()
        error = None
        token = None
        # update the systemid/serverid if need be.
        self.__processSystemid()
        # Makes three attempts to login
        for _i in range(self.__nRetries):
            try:
                token = server.proxy.login(self.__systemid)
            except (socket.error, socket.sslerror), e:
                if CFG.HTTP_PROXY:
                    # socket error, check to see if your HTTP proxy is running...
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    httpProxy, httpProxyPort = CFG.HTTP_PROXY.split(':')
                    try:
                        s.connect((httpProxy, int(httpProxyPort)))
                    except socket.error, e:
                        error = ['socket.error', 'HTTP Proxy not running? '
                                 '(%s) %s' % (CFG.HTTP_PROXY, e)]
                        # rather big problem: http proxy not running.
                        log_error("*** ERROR ***: %s" % error[1])
                        Traceback(mail=0)
                    except socket.sslerror, e:
                        error = ['socket.sslerror',
                                 '(%s) %s' % (CFG.HTTP_PROXY, e)]
                        # rather big problem: http proxy not running.
                        log_error("*** ERROR ***: %s" % error[1])
                        Traceback(mail=0)
                    else:
                        error = ['socket', str(e)]
                        log_error(error)
                        Traceback(mail=0)
Ejemplo n.º 17
0
    def add_hardware(self, hardware):
        """ add new hardware """
        log_debug(4, hardware)
        if not hardware:
            return -1
        if type(hardware) == type({}):
            hardware = UserDictCase(hardware)
        if not isinstance(hardware, UserDictCase):
            log_error("argument type is not  hash: %s" % hardware)
            raise TypeError("This function requires a hash as an argument")
        # validation is important
        hw_class = hardware.get("class")
        if hw_class is None:
            return -1
        hw_class = hw_class.lower()

        class_type = None

        if hw_class in [
                "video", "audio", "audio_hd", "usb", "other", "hd", "floppy",
                "mouse", "modem", "network", "cdrom", "scsi", "unspec",
                "scanner", "tape", "capture", "raid", "socket", "keyboard",
                "printer", "firewire", "ide"
        ]:
            class_type = HardwareDevice
        elif hw_class == "cpu":
            class_type = CPUDevice
        elif hw_class == "memory":
            class_type = MemoryInformation
        elif hw_class == "dmi":
            class_type = DMIInformation
        elif hw_class == "installinfo":
            class_type = InstallInformation
        elif hw_class == "netinterfaces":
            class_type = NetIfaceInformation
        elif hw_class == "fqdn":
            class_type = FQDNInformation
        elif hw_class == "sysinfo":
            # special case: we got info about a virtual host
            # where this system is running on
            SystemInformation(hardware, self)
            return 0
        elif hw_class == "machineinfo":
            MachineInformation(self.server["id"], self.server["name"],
                               hardware)
            return 0
        else:
            log_error("UNKNOWN CLASS TYPE `%s'" % hw_class)
            # Same trick: try-except and raise the exception so that Traceback
            # can send the e-mail
            try:
                raise KeyError("Unknown class type `%s' for hardware '%s'" %
                               (hw_class, hardware))
            except:
                Traceback(mail=1)
                return

        # create the new device
        new_dev = class_type(hardware)

        if class_type in self.__hardware:
            _l = self.__hardware[class_type]
        else:
            _l = self.__hardware[class_type] = []
        _l.append(new_dev)
        self.__changed = 1
        return 0
Ejemplo n.º 18
0
            # Normalize the response
            response = self.normalize(response)
            try:
                response = rpclib.xmlrpclib.dumps(response, methodresponse=1)
            except TypeError, e:
                log_debug(
                    -1, "Error \"%s\" encoding response = %s" % (e, response))
                Traceback("apacheHandler.response",
                          req,
                          extra="Error \"%s\" encoding response = %s" %
                          (e, response),
                          severity="notification")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            except:
                # Uncaught exception; signal the error
                Traceback("apacheHandler.response", req, severity="unhandled")
                return apache.HTTP_INTERNAL_SERVER_ERROR

        # we're about done here, patch up the headers
        output.process(response)
        # Copy the rest of the fields
        for k, v in output.headers.items():
            if k.lower() == 'content-type':
                # Content-type
                req.content_type = v
            else:
                setHeaderValue(req.headers_out, k, v)

        if CFG.DEBUG == 4:
            # I wrap this in an "if" so we don't parse a large file for no reason.
            log_debug(
Ejemplo n.º 19
0
    def response(self, response):
        # Send the xml-rpc response back
        log_debug(3, type(response))
        needs_xmlrpc_encoding = not rhnFlags.test("XMLRPC-Encoded-Response")
        compress_response = rhnFlags.test("compress_response")
        # Init an output object; we'll use it for sending data in various
        # formats
        if isinstance(response, transports.File):
            if not hasattr(response.file_obj, 'fileno') and compress_response:
                # This is a StringIO that has to be compressed, so read it in
                # memory; mark that we don't have to do any xmlrpc encoding
                response = response.file_obj.read()
                needs_xmlrpc_encoding = 0
            else:
                # Just treat is as a file
                return self.response_file(response)

        output = transports.Output()

        # First, use the same encoding/transfer that the client used
        output.set_transport_flags(
            transfer=transports.lookupTransfer(self.input.transfer),
            encoding=transports.lookupEncoding(self.input.encoding))

        if isinstance(response, xmlrpclib.Fault):
            log_debug(4, "Return FAULT",
                      response.faultCode, response.faultString)
            # No compression for faults because we'd like them to pop
            # up in clear text on the other side just in case
            output.set_transport_flags(output.TRANSFER_NONE, output.ENCODE_NONE)
        elif compress_response:
            # check if we have to compress this result
            log_debug(4, "Compression on for client version", self.client)
            if self.client > 0:
                output.set_transport_flags(output.TRANSFER_BINARY,
                                           output.ENCODE_ZLIB)
            else:  # original clients had the binary transport support broken
                output.set_transport_flags(output.TRANSFER_BASE64,
                                           output.ENCODE_ZLIB)

        # We simply add the transport options to the output headers
        output.headers.update(rhnFlags.get('outputTransportOptions').dict())

        if needs_xmlrpc_encoding:
            # Normalize the response
            response = self.normalize(response)
            try:
                response = xmlrpclib.dumps(response, methodresponse=1)
            except TypeError:
                e = sys.exc_info()[1]
                log_debug(4, "Error \"%s\" encoding response = %s" % (e, response))
                Traceback("apacheHandler.response", self.req,
                          extra="Error \"%s\" encoding response = %s" % (e, response),
                          severity="notification")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            except:
                # Uncaught exception; signal the error
                Traceback("apacheHandler.response", self.req,
                          severity="unhandled")
                return apache.HTTP_INTERNAL_SERVER_ERROR

        # we're about done here, patch up the headers
        output.process(response)
        # Copy the rest of the fields
        for k, v in output.headers.items():
            if string.lower(k) == 'content-type':
                # Content-type
                self.req.content_type = v
            else:
                setHeaderValue(self.req.headers_out, k, v)

        if 5 <= CFG.DEBUG < 10:
            log_debug(5, "The response: %s[...SNIP (for sanity) SNIP...]%s" % (response[:100], response[-100:]))
        elif CFG.DEBUG >= 10:
            # if you absolutely must have that whole response in the log file
            log_debug(10, "The response: %s" % response)

        # send the headers
        self.req.send_http_header()
        try:
            # XXX: in case data is really large maybe we should split
            # it in smaller chunks instead of blasting everything at
            # once. Not yet a problem...
            self.req.write(output.data)
        except IOError:
            # send_http_header is already sent, so it doesn't make a lot of
            # sense to return a non-200 error; but there is no better solution
            return apache.HTTP_BAD_REQUEST
        del output
        return apache.OK
Ejemplo n.º 20
0
    def login(self):
        """ Login and fetch new token (proxy token).

            How it works in a nutshell.
            Only the broker component uses this. We perform a xmlrpc request
            to rhn_parent. This occurs outside of the http process we are
            currently working on. So, we do this all on our own; do all of
            our own SSL decisionmaking etc. We use CFG.RHN_PARENT as we always
            bypass the SSL redirect.

            DESIGN NOTES:  what is the proxy auth token?
            -------------------------------------------
            An SUSE Manager Proxy auth token is a token fetched upon login from
            SUSE Manager Server or hosted.

            It has this format:
               'S:U:ST:EO:SIG'
            Where:
               S   = server ID
               U   = username
               ST  = server time
               EO  = expiration offset
               SIG = signature
               H   = hostname (important later)

            Within this function within the SUSE Manager Proxy Broker we also tag on
            the hostname to the end of the token. The token as described above
            is enough for authentication purposes, but we need a to identify
            the exact hostname (as the SUSE Manager Proxy sees it). So now the token
            becomes (token:hostname):
               'S:U:ST:EO:SIG:H'

            DESIGN NOTES:  what is X-RHN-Proxy-Auth?
            -------------------------------------------
            This is where we use the auth token beyond SUSE Manager Proxy login
            purposes. This a header used to track request routes through
            a hierarchy of SUSE Manager Proxies.

            X-RHN-Proxy-Auth is a header that passes proxy authentication
            information around in the form of an ordered list of tokens. This
            list is used to gain information as to how a client request is
            routed throughout an RHN topology.

            Format: 'S1:U1:ST1:EO1:SIG1:H1,S2:U2:ST2:EO2:SIG2:H2,...'
                     |_________1_________| |_________2_________| |__...
                             token                 token
                     where token is really: token:hostname

            leftmost token was the first token hit by a client request.
            rightmost token was the last token hit by a client request.

        """
        # pylint: disable=R0915

        log_debug(3)
        server = self.__getXmlrpcServer()
        error = None
        token = None
        # update the systemid/serverid if need be.
        self.__processSystemid()
        # Makes three attempts to login
        for _i in range(self.__nRetries):
            try:
                token = server.proxy.login(self.__systemid)
            except (socket.error, socket_error) as e:
                if CFG.HTTP_PROXY:
                    # socket error, check to see if your HTTP proxy is running...
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    httpProxy, httpProxyPort = CFG.HTTP_PROXY.split(':')
                    try:
                        s.connect((httpProxy, int(httpProxyPort)))
                    except socket.error as e:
                        error = [
                            'socket.error',
                            'HTTP Proxy not running? '
                            '(%s) %s' % (CFG.HTTP_PROXY, e)
                        ]
                        # rather big problem: http proxy not running.
                        log_error("*** ERROR ***: %s" % error[1])
                        Traceback(mail=0)
                    except socket_error as e:  # pylint: disable=duplicate-except
                        error = [
                            'socket.sslerror',
                            '(%s) %s' % (CFG.HTTP_PROXY, e)
                        ]
                        # rather big problem: http proxy not running.
                        log_error("*** ERROR ***: %s" % error[1])
                        Traceback(mail=0)
                    else:
                        error = ['socket', str(e)]
                        log_error(error)
                        Traceback(mail=0)
                else:
                    log_error("Socket error", e)
                    Traceback(mail=0)
                Traceback(mail=1)
                token = None
                time.sleep(.25)
                continue
            except SSL.SSL.SSLError as e:
                token = None
                error = ['rhn.SSL.SSL.SSLError', repr(e), str(e)]
                log_error(error)
                Traceback(mail=0)
                time.sleep(.25)
                continue
            except xmlrpclib.ProtocolError as e:
                token = None
                log_error('xmlrpclib.ProtocolError', e)
                time.sleep(.25)
                continue
            except xmlrpclib.Fault as e:
                # Report it through the mail
                # Traceback will try to walk over all the values
                # in each stack frame, and eventually will try to stringify
                # the method object itself
                # This should trick it, since the originator of the exception
                # is this function, instead of a deep call into xmlrpclib
                log_error("%s" % e)
                if e.faultCode == 10000:
                    # reraise it for the users (outage or "important message"
                    # coming through")
                    raise_with_tb(rhnFault(e.faultCode, e.faultString),
                                  sys.exc_info()[2])
                # ok... it's some other fault
                Traceback("ProxyAuth.login (Fault) - SUSE Manager Proxy not "
                          "able to log in.")
                # And raise a Proxy Error - the server made its point loud and
                # clear
                raise_with_tb(
                    rhnFault(
                        1000,
                        _("SUSE Manager Proxy error (during proxy login). "
                          "Please contact your system administrator.")),
                    sys.exc_info()[2])
            except Exception as e:  # pylint: disable=broad-except
                token = None
                log_error("Unhandled exception", e)
                Traceback(mail=0)
                time.sleep(.25)
                continue
            else:
                break

        if not token:
            if error:
                if error[0] in ('xmlrpclib.ProtocolError', 'socket.error',
                                'socket'):
                    raise rhnFault(
                        1000,
                        _("SUSE Manager Proxy error (error: %s). "
                          "Please contact your system administrator.") %
                        error[0])
                if error[0] in ('rhn.SSL.SSL.SSLError', 'socket.sslerror'):
                    raise rhnFault(
                        1000,
                        _("SUSE Manager Proxy error (SSL issues? Error: %s). "
                          "Please contact your system administrator.") %
                        error[0])
                raise rhnFault(1002, err_text='%s' % e)
            raise rhnFault(1001)
        if self.hostname:
            token = token + ':' + self.hostname
        log_debug(6, "New proxy token: %s" % token)
        return token
Ejemplo n.º 21
0
class Shelf:
    """ Client authenication temp. db.

        Main class that the client side (client to the caching daemon) has to
        instantiate to expose the proper API. Basically, the API is a dictionary.
    """

    # pylint: disable=R0903

    def __init__(self, server_addr):
        log_debug(6, server_addr)
        self.serverAddr = server_addr

    def __request(self, methodname, params):
        # pylint: disable=R0915
        log_debug(6, methodname, params)
        # Init the socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            sock.connect(self.serverAddr)
        except socket.error, e:
            sock.close()
            methodname = None
            log_error("Error connecting to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""
              Error connecting to the the authentication cache daemon.
              Make sure it is started on %s""" % str(self.serverAddr))
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (issues connecting to auth cache). "
                  "Please contact your system administrator")
            ), None, sys.exc_info()[2]

        wfile = sock.makefile("w")

        try:
            send(wfile, methodname, None, *params)
        except CommunicationError:
            wfile.close()
            sock.close()
            Traceback("Shelf.__request",
                      extra="Encountered a CommunicationError")
            raise
        except socket.error:
            wfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                     Error sending to the authentication cache daemon.
                     Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (issues connecting to auth cache). "
                  "Please contact your system administrator")
            ), None, sys.exc_info()[2]

        wfile.close()

        rfile = sock.makefile("r")
        try:
            params, methodname = recv(rfile)
        except CommunicationError, e:
            log_error(e.faultString)
            rfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                      Error receiving from the authentication cache daemon.
                      Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (issues communicating to auth cache). "
                  "Please contact your system administrator")
            ), None, sys.exc_info()[2]
Ejemplo n.º 22
0
    def __request(self, methodname, params):
        # pylint: disable=R0915
        log_debug(6, methodname, params)
        # Init the socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            sock.connect(self.serverAddr)
        except socket.error as e:
            sock.close()
            methodname = None
            log_error("Error connecting to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""
              Error connecting to the the authentication cache daemon.
              Make sure it is started on %s""" % str(self.serverAddr))
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues connecting to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])

        wfile = sock.makefile("w")

        try:
            send(wfile, methodname, None, *params)
        except CommunicationError:
            wfile.close()
            sock.close()
            Traceback("Shelf.__request",
                      extra="Encountered a CommunicationError")
            raise
        except socket.error:
            wfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                     Error sending to the authentication cache daemon.
                     Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues connecting to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])

        wfile.close()

        rfile = sock.makefile("r")
        try:
            params, methodname = recv(rfile)
        except CommunicationError as e:
            log_error(e.faultString)
            rfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                      Error receiving from the authentication cache daemon.
                      Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues communicating to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])
        except Fault as e:
            rfile.close()
            sock.close()
            # If e.faultCode is 0, it's another exception
            if e.faultCode != 0:
                # Treat is as a regular xmlrpc fault
                raise

            _dict = e.faultString
            if not isinstance(_dict, type({})):
                # Not the expected type
                raise

            if 'name' not in _dict:
                # Doesn't look like a marshalled exception
                raise

            name = _dict['name']
            args = _dict.get('args')
            # Look up the exception
            if not hasattr(__builtins__, name):
                # Unknown exception name
                raise

            # Instantiate the exception object
            import new
            _dict = {'args': args}
            # pylint: disable=bad-option-value,nonstandard-exception
            raise_with_tb(new.instance(getattr(__builtins__, name), _dict),
                          sys.exc_info()[2])

        return params[0]
Ejemplo n.º 23
0
            response = connection.getresponse()
        except IOError, ioe:
            # Raised by getresponse() if server closes connection on us.
            log_error("Redirect connection reset by peer.", redirectLocation,
                      ioe)
            Traceback(mail=0)

            # The connection is saved in the current response context, and
            # will be closed when the caller pops the context.
            return apache.HTTP_SERVICE_UNAVAILABLE

        except socket.error, se:
            # Some socket error occurred.  Possibly a read error.
            log_error("Redirect request failed.", redirectLocation, se)
            Traceback(mail=0)

            # The connection is saved in the current response context, and
            # will be closed when the caller pops the context.
            return apache.HTTP_SERVICE_UNAVAILABLE

        # Save the response headers and body FD in the current communication
        # context.

        self.responseContext.setBodyFd(response)
        self.responseContext.setHeaders(response.msg)

        log_debug(4, "Response headers: ",
                  self.responseContext.getHeaders().items())
        log_debug(4, "Got redirect response.  Status=", response.status)
Ejemplo n.º 24
0
    def __request(self, methodname, params):
        # pylint: disable=R0915
        log_debug(6, methodname, params)
        # Init the socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            sock.connect(self.serverAddr)
        except socket.error as e:
            sock.close()
            methodname = None
            log_error("Error connecting to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""
              Error connecting to the the authentication cache daemon.
              Make sure it is started on %s""" % str(self.serverAddr))
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues connecting to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])

        wfile = sock.makefile("w")

        try:
            send(wfile, methodname, None, *params)
        except CommunicationError:
            wfile.close()
            sock.close()
            Traceback("Shelf.__request",
                      extra="Encountered a CommunicationError")
            raise
        except socket.error:
            wfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                     Error sending to the authentication cache daemon.
                     Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues connecting to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])

        wfile.close()

        rfile = sock.makefile("r")
        try:
            params, methodname = recv(rfile)
        except CommunicationError as e:
            log_error(e.faultString)
            rfile.close()
            sock.close()
            log_error("Error communicating to the auth cache: %s" % str(e))
            Traceback("Shelf.__request",
                      extra="""\
                      Error receiving from the authentication cache daemon.
                      Make sure the authentication cache daemon is started""")
            # FIXME: PROBLEM: this rhnFault will never reach the client
            raise_with_tb(
                rhnFault(
                    1000,
                    _("Spacewalk Proxy error (issues communicating to auth cache). "
                      "Please contact your system administrator")),
                sys.exc_info()[2])
        except Fault as e:
            rfile.close()
            sock.close()
            raise

        return params[0]