Esempio n. 1
0
def _verifyProxyAuthToken(auth_token):
    """ verifies the validity of a proxy auth token

        NOTE: X-RHN-Proxy-Auth described in proxy/broker/rhnProxyAuth.py
    """

    log_debug(4, auth_token)
    token, hostname = splitProxyAuthToken(auth_token)
    hostname = hostname.strip()
    ipv4_regex = '^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$'
    # This ipv6 regex was develeoped by Stephen Ryan at Dataware.
    # (http://forums.intermapper.com/viewtopic.php?t=452) It is licenced
    # under a Creative Commons Attribution-ShareAlike 3.0 Unported
    # License, so we are free to use it as long as we attribute it to him.
    ipv6_regex = '^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?$'
    hostname_is_ip_address = re.match(ipv4_regex, hostname) or re.match(ipv6_regex, hostname)

    headers = rhnFlags.get('outputTransportOptions')
    if len(token) < 5:
        # Bad auth information; decline any action
        log_debug(4, "incomplete proxy authentication token: %s"
                  % auth_token)
        headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (
            1003, _("incomplete proxy authentication token: %s") % auth_token)
        if not hostname_is_ip_address:
            headers['X-RHN-Proxy-Auth-Origin'] = hostname
        raise rhnFault(1003)  # Invalid session key

    log_debug(5, "proxy auth token: %s,  hostname: %s"
                 % (repr(token), hostname or 'n/a'))

    proxyId, proxyUser, rhnServerTime, expireOffset, signature = token[:5]
    computed = computeSignature(CFG.SECRET_KEY, proxyId, proxyUser,
                                rhnServerTime, expireOffset)

    if computed != signature:
        log_error("Proxy signature failed: proxy id='%s', proxy user='******'" %
                  (proxyId, proxyUser))
        log_debug(4, "Sent proxy signature %s does not match ours %s." % (
            signature, computed))
        headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (
            1003, _("Sent proxy signature %s does not match ours %s.") % (
                signature, computed))
        if not hostname_is_ip_address:
            headers['X-RHN-Proxy-Auth-Origin'] = hostname
        raise rhnFault(1003)  # Invalid session key

    # Convert the expiration/time to floats:
    rhnServerTime = float(rhnServerTime)
    expireOffset = float(expireOffset)

    if rhnServerTime + expireOffset < time.time():
        log_debug(4, "Expired proxy authentication token")
        headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (1004, "Expired")
        if not hostname_is_ip_address:
            headers['X-RHN-Proxy-Auth-Origin'] = hostname
        raise rhnFault(1004)  # Expired client authentication token

    log_debug(4, "Proxy auth OK: sigs match; not an expired token")
    return 1
Esempio n. 2
0
    def getAnyChecksum(self, info, username=None, password=None, session=None, is_source=0):
        """ returns checksum info of available packages
            also does an existance check on the filesystem.
        """
        log_debug(3)

        pkg_infos = info.get('packages')
        channels = info.get('channels', [])
        force = info.get('force', 0)
        orgid = info.get('org_id')

        if orgid == 'null':
            null_org = 1
        else:
            null_org = None

        if not session:
            org_id, force = rhnPackageUpload.authenticate(username, password,
                                                          channels=channels,
                                                          null_org=null_org,
                                                          force=force)
        else:
            try:
                org_id, force = rhnPackageUpload.authenticate_session(
                    session, channels=channels, null_org=null_org, force=force)
            except rhnSession.InvalidSessionError:
                raise_with_tb(rhnFault(33), sys.exc_info()[2])
            except rhnSession.ExpiredSessionError:
                raise_with_tb(rhnFault(34), sys.exc_info()[2])

        if is_source:
            ret = self._getSourcePackageChecksum(org_id, pkg_infos)
        else:
            ret = self._getPackageChecksum(org_id, pkg_infos)
        return ret
Esempio n. 3
0
 def __init__(self, dict=None):
     log_debug(4, dict)
     self.ifaces = {}
     self.db_ifaces = []
     # parameters which are not allowed to be empty and set to NULL
     self._autonull = ('hw_addr', 'module')
     if not dict:
         return
     for name, info in dict.items():
         if name == 'class':
             # Ignore it
             continue
         if not isinstance(info, type({})):
             raise rhnFault(53, "Unexpected format for interface %s" %
                            name)
         vdict = {}
         for key, mapping in self.key_mapping.items():
             # Look at the mapping first; if not found, look for the key
             if info.has_key(mapping):
                 k = mapping
             else:
                 k = key
             if not info.has_key(k):
                 raise rhnFault(53, "Unable to find required field %s"
                                % key)
             val = info[k]
             vdict[mapping] = val
         if 'ipaddr' in info and info['ipaddr']:
             vdict['ipv4'] = NetIfaceAddress4(
                 [{'ipaddr': info['ipaddr'], 'broadcast': info['broadcast'], 'netmask': info['netmask']}])
         if 'ipv6' in info and info['ipv6']:
             vdict['ipv6'] = NetIfaceAddress6(info["ipv6"])
         self.ifaces[name] = vdict
Esempio n. 4
0
    def new_user(self, username, password, email = None,
                 org_id = None, org_password = None):
        """
        Finish off creating the user.

        The user has to exist (must be already reserved), the password must
        match and we set the e-mail address if one is given

        Return true if success
        """

        log_debug(1, username, email)
        # email has to be a string or nothing
        if not checkValue(email, None, "", type("")):
            raise rhnFault(30, _faultValueString(email, "email"))
        # be somewhat drastic about the org values
        if org_id and org_password:
            org_password = str(org_password)
            try:
                org_id = int(str(org_id))
            except ValueError:
                raise rhnFault(30, _faultValueString(org_id, "org_id")), None, sys.exc_info()[2]
        else:
            org_id = org_password = None
        username, password  = rhnUser.check_user_password(username, password)
        email = rhnUser.check_email(email)
        # now create this user
        ret = rhnUser.new_user(username, password, email, org_id, org_password)
        # rhnUser.new_user will raise it's own faults.
        return ret
Esempio n. 5
0
    def update_crash_count(self, system_id, crash, crash_count):
        self.auth_system(system_id)

        log_debug(1, self.server_id, "Updating crash count for %s to %s" % (crash, crash_count))

        server_org_id = self.server.server['org_id']
        server_crash_dir = get_crash_path(str(server_org_id), str(self.server_id), crash)
        if not server_crash_dir:
            log_debug(1, self.server_id, "Error composing crash directory path")
            raise rhnFault(5002)

        h = rhnSQL.prepare(_query_update_crash_count)
        r = h.execute(
            crash_count=crash_count,
            server_id=self.server_id,
            crash=crash)
        rhnSQL.commit()

        if r == 0:
            log_debug(1, self.server_id, "No record for crash: %s" % crash)
            raise rhnFault(5005, "Invalid crash name: %s" % crash)

        absolute_dir = os.path.join(CFG.MOUNT_POINT, server_crash_dir)
        absolute_file = os.path.join(absolute_dir, 'count')

        log_debug(1, self.server_id, "Updating crash count file: %s" % absolute_file)
        f = open(absolute_file, 'w+')
        f.write(crash_count)
        f.close()

        return 1
Esempio n. 6
0
    def auth_client(self, token):
        """ Authenticate a system based on the same authentication tokens
            the client is sending for GET requests
        """
        log_debug(3)
        # Build a UserDictCase out of the token
        dict = UserDictCase(token)
        # Set rhnFlags so that we can piggyback on apacheAuth's auth_client
        rhnFlags.set('AUTH_SESSION_TOKEN', dict)

        # XXX To clean up apacheAuth.auth_client's logging, this is not about
        # GET requests
        result = apacheAuth.auth_client()

        if not result:
            raise rhnFault(33, _("Invalid session key"))

        log_debug(4, "Client auth OK")
        # We checked it already, so we're sure it's there
        client_id = dict['X-RHN-Server-Id']

        server = rhnServer.search(client_id)
        if not server:
            raise rhnFault(8, _("This server ID no longer exists"))
        # XXX: should we check if the username still has access to it?
        # probably not, because there is no known good way we can
        # update the server system_id on the client side when
        # permissions change... Damn it. --gafton
        self.server = server
        self.server_id = client_id
        self.user = dict['X-RHN-Auth-User-Id']
        return server
Esempio n. 7
0
def check_user_password(username, password):
    """ Do some minimal checks on the data thrown our way. """
    # username is required
    if not username:
        raise rhnFault(11)
    # password is required
    if not password:
        raise rhnFault(12)
    if len(username) < CFG.MIN_USER_LEN:
        raise rhnFault(13, _("username should be at least %d characters")
                       % CFG.MIN_USER_LEN)
    if len(username) > CFG.MAX_USER_LEN:
        raise rhnFault(700, _("username should be less than %d characters")
                       % CFG.MAX_USER_LEN)
    username = username[:CFG.MAX_USER_LEN]

    # Invalid characters
    # ***NOTE*** Must coordinate with web and installer folks about any
    # changes to this set of characters!!!!
    invalid_re = re.compile(".*[\s&+%'`\"=#]", re.I)
    tmp = invalid_re.match(username)
    if tmp is not None:
        pos = tmp.regs[0]
        raise rhnFault(15, _("username = `%s', invalid character `%s'") % (
            username, username[pos[1] - 1]))

    # use new password validation method
    validate_new_password(password)

    return username, password
Esempio n. 8
0
    def valid(self):
        log_debug(4)
        # check for anonymous

        if self.attrs.get('machine_id'):
            entitlements = check_entitlement_by_machine_id(self.attrs.get('machine_id'))
            log_debug(4, "found entitlements for machine_id", self.attrs.get('machine_id'), entitlements)
            if 'salt_entitled' in entitlements:
                raise rhnFault(48, """
    This system is already registered as a Salt Minion. If you want to register it as a traditional client
    please delete it first via the web UI or API and then register it using the traditional tools.
                """)

        if 'type' in self.attrs and self.attrs['type'] \
                and string.upper(self.attrs['type']) == "ANONYMOUS":
            raise rhnFault(28, """
            You need to re-register your system with SUSE Manager.
            Previously you have chosen to skip the creation of a system profile
            with SUSE Manager and this trial feature is no longer available now.
            """) # we don't support anonymous anymore
        # now we have a real server. Get its secret
        sid = self.attrs["system_id"]
        secret = getServerSecret(sid)
        if secret is None:
            # no secret, can't validate
            log_debug(1, "Server id %s not found in database" % sid)
            return 0
        return self.__validate_checksum(secret)
Esempio n. 9
0
    def authzOrg(self, info):
        # This function is a lot more complicated than it should be; the
        # corner case is pushes without a channel; we have to deny regular
        # users the ability to push to their org.

        # If the org id is not specified, default to the user's org id
        if not info.has_key("orgId"):
            info["orgId"] = self.org_id
        log_debug(4, "info[orgId]", info["orgId"], "org id", self.org_id)

        org_id = info["orgId"]

        if org_id == "":
            # Satellites are not allowwd to push in the null org
            raise rhnFault(4, _("You are not authorized to manage packages in the null org"))

        if org_id and self.org_id != org_id:
            # Not so fast...
            raise rhnFault(32, _("You are not allowed to manage packages in the %s org") % org_id)

        # Org admins and channel admins have full privileges; we could use
        # user_manages_channes, except for the case where there are no chanels

        if self.isOrgAdmin() or self.isChannelAdmin():
            log_debug(4, "Org authorized (org_admin or channel_admin)")
            return

        # regular user at this point... check if the user manages any channels
        if user_manages_channels(self.user_id):
            log_debug(4, "Org authorized (user manages a channel)")
            return

        # ok, you're a regular user who doesn't manage any channels.
        # take a hike.
        raise rhnFault(32, _("You are not allowed to perform administrative tasks"))
    def management_remove_channel(self, dict):
        log_debug(1)
        self._get_and_validate_session(dict)

        config_channel = dict.get('config_channel')
        # XXX Validate the namespace

        row = rhnSQL.fetchone_dict(self._query_config_channel_by_label,
                                   org_id=self.org_id, label=config_channel)

        if not row:
            raise rhnFault(4009, "Channel not found")

        delete_call = rhnSQL.Procedure('rhn_config.delete_channel')

        try:
            delete_call(row['id'])
        except rhnSQL.SQLError:
            e = sys.exc_info()[1]
            errno = e.args[0]
            if errno == 2292:
                raise_with_tb(rhnFault(4005, "Cannot remove non-empty channel %s" %
                               config_channel, explain=0), sys.exc_info()[2])
            raise

        log_debug(5, "Removed:", config_channel)
        rhnSQL.commit()
        return ""
Esempio n. 11
0
def get_package_path(server_id, pkg_spec, channel):
    log_debug(3, server_id, pkg_spec, channel)
    if isinstance(pkg_spec, ListType):
        pkg = pkg_spec[:4]
        #Insert EPOCH
        pkg.insert(1, None)
    else:
        pkg = parseRPMFilename(pkg_spec)
        if pkg is None:
            log_debug(4, "Error", "Requested weird package", pkg_spec)
            raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec)

    statement = """
        select  p.id, p.path path, pe.epoch epoch
        from
                rhnPackageArch pa,
                rhnChannelPackage cp,
                rhnPackage p,
                rhnPackageEVR pe,
                rhnServerChannel sc,
                rhnPackageName pn,
                rhnChannel c
        where 1=1
            and c.label = :channel
            and pn.name = :name
            and sc.server_id = :server_id
            and pe.version = :ver
            and pe.release = :rel
            and c.id = sc.channel_id
            and c.id = cp.channel_id
            and pa.label = :arch
            and pn.id = p.name_id
            and p.id = cp.package_id
            and p.evr_id = pe.id
            and sc.channel_id = cp.channel_id
            and p.package_arch_id = pa.id
    """
    h = rhnSQL.prepare(statement)
    pkg = map(str, pkg)
    h.execute(name = pkg[0], ver = pkg[2], rel = pkg[3], arch = pkg[4],
              channel = channel, server_id = server_id)
    rs = h.fetchall_dict()
    if not rs:
        log_debug(4, "Error", "Non-existant package requested", server_id,
            pkg_spec, channel)
        raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec)
    # It is unlikely for this query to return more than one row,
    # but it is possible
    # (having two packages with the same n, v, r, a and different epoch in
    # the same channel is prohibited by the RPM naming scheme; but extra
    # care won't hurt)
    max_row = rs[0]
    for each in rs[1:]:
        # Compare the epoch as string
        if _none2emptyString(each['epoch']) > _none2emptyString(max_row['epoch']):
            max_row = each

    # Set the flag for the proxy download accelerator
    rhnFlags.set("Download-Accelerator-Path", max_row['path'])
    return check_package_file(max_row['path'], max_row['id'], pkg_spec), max_row['id']
Esempio n. 12
0
 def __init__(self, list_ifaces=None):
     log_debug(4, list_ifaces)
     self.ifaces = {}
     self.db_ifaces = []
     # parameters which are not allowed to be empty and set to NULL
     self._autonull = ('address', 'netmask')
     self.sequence = "rhn_srv_net_iface_id_seq"
     if not list_ifaces:
         return
     for info in list_ifaces:
         if not isinstance(info, type({})):
             raise rhnFault(53, "Unexpected format for interface %s" %
                            info)
         vdict = {}
         for key, mapping in self.key_mapping.items():
             # Look at the mapping first; if not found, look for the key
             if info.has_key(mapping):
                 k = mapping
             else:
                 k = key
             if not info.has_key(k):
                 raise rhnFault(53, "Unable to find required field %s"
                                % (key))
             val = info[k]
             if mapping in ['ip_addr', 'netmask', 'broadcast', 'address']:
                 # bugzilla: 129840 kudzu (rhpl) will sometimes pad octets
                 # with leading zeros, causing confusion; clean those up
                 val = self.cleanse_ip_addr(val)
             vdict[mapping] = val
         self.ifaces[vdict['address']] = vdict
Esempio n. 13
0
    def _store_file(self, action_id, scap_file):
        r_dir = get_action_path(self.server.server['org_id'], self.server_id, action_id)
        if not r_dir:
            log_debug(1, self.server_id, "Error composing SCAP action directory path")
            raise rhnFault(5102)
        r_file = get_actionfile_path(self.server.server['org_id'], self.server_id, action_id, scap_file['filename'])
        if not r_file:
            log_debug(1, self.server_id, "Error composing SCAP action file path")
            raise rhnFault(5103)

        if not scap_file['content-encoding'] == 'base64':
            log_debug(1, self.server_id, "Invalid content encoding: %s" % scap_file['content-encoding'])
            raise rhnFault(5104)

        # Create the file on filer
        filecontent = decodestring(scap_file['filecontent'])
        # TODO assert for the size of the file

        absolute_dir = os.path.join(CFG.MOUNT_POINT, r_dir)
        absolute_file = os.path.join(absolute_dir, scap_file['filename'])

        if not os.path.exists(absolute_dir):
            log_debug(1, self.server_id, "Creating action directory: %s" % absolute_dir)
            os.makedirs(absolute_dir)
            mode = stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH
            os.chmod(absolute_dir, mode)
            os.chmod(os.path.dirname(os.path.normpath(absolute_dir)), mode)
        log_debug(1, self.server_id, "Creating file: %s" % absolute_file)
        f = open(absolute_file, 'w+')
        f.write(filecontent)
        return {'result': True,
                }
Esempio n. 14
0
    def _repodata_taskomatic(self, file_name):
        log_debug(3, 'repodata', file_name)

        content_type = "application/x-gzip"

        if file_name in ["repomd.xml", "comps.xml"]:
            content_type = "text/xml"
        elif file_name not in ["primary.xml.gz", "other.xml.gz",
                               "filelists.xml.gz", "updateinfo.xml.gz", "Packages.gz"]:
            log_debug(2, "Unknown repomd file requested: %s" % file_name)
            raise rhnFault(6)

        # XXX this won't be repconned or CDNd
        if file_name == "comps.xml":
            return self._repodata_python(file_name)

        file_path = "%s/%s/%s" % (CFG.REPOMD_PATH_PREFIX, self.channelName, file_name)
        rhnFlags.set('Content-Type', content_type)
        try:
            rhnFlags.set('Download-Accelerator-Path', file_path)
            return self._getFile(CFG.REPOMD_CACHE_MOUNT_POINT + "/" + file_path)
        except IOError, e:
            # For file not found, queue up a regen, and return 404
            if e.errno == 2 and file_name != "comps.xml":
                taskomatic.add_to_repodata_queue(self.channelName,
                                                 "repodata request", file_name, bypass_filters=True)
                rhnSQL.commit()
                # This returns 404 to the client
                raise rhnFault(6), None, sys.exc_info()[2]
            raise
Esempio n. 15
0
def __processPackage(package, org_id, channels, source):
    log_debug(4, org_id, channels, source)
    if 'md5sum' in package:  # for old rhnpush compatibility
        package['checksum_type'] = 'md5'
        package['checksum'] = package['md5sum']
        del(package['md5sum'])

    if 'checksum' not in package:
        raise rhnFault(50, "The package's checksum digest has not been specified")
    if 'packageSize' not in package:
        raise rhnFault(50, "The package size has not been specified")

    header = rhn_rpm.headerLoad(package['header'].data)
    if not header:
        raise rhnFault(50)
    packageSize = package['packageSize']
    relpath = package.get('relativePath')

    if 'header_start' in package:
        header_start = package['header_start']
    else:
        header_start = 0
    if 'header_end' in package:
        header_end = package['header_end']
    else:
        # Just say the whole package
        header_end = packageSize

    checksum_type = package['checksum_type']
    checksum = package['checksum']
    p = createPackage(header, packageSize, checksum_type, checksum, relpath, org_id,
                      header_start, header_end, channels)
    return p
    def getSourcePackagePath(self, pkgFilename):
        """ OVERLOADS getSourcePackagePath in common/rhnRepository.
            snag src.rpm and nosrc.rpm from local repo, after ensuring
            we are authorized to fetch it.
        """

        log_debug(3, pkgFilename)
        if pkgFilename[-8:] != '.src.rpm' and pkgFilename[-10:] != '.nosrc.rpm':
            raise rhnFault(17, _("Invalid SRPM package requested: %s")
                                 % pkgFilename)

        # Connect to the server to get an authorization for downloading this
        # package
        server = rpclib.Server(self.rhnParentXMLRPC, proxy=self.httpProxy,
                               username=self.httpProxyUsername,
                               password=self.httpProxyPassword)
        if self.caChain:
            server.add_trusted_cert(self.caChain)

        try:
            retval = server.proxy.package_source_in_channel(
                        pkgFilename, self.channelName, self.clientInfo)
        except xmlrpclib.Fault, e:
            raise rhnFault(1000,
                    _("Error retrieving source package: %s") % str(e)), None, sys.exc_info()[2]
    def management_diff(self, dict):
        log_debug(1)
        self._get_and_validate_session(dict)

        param_names = ['config_channel_src', 'revision_src', 'path', ]
        for p in param_names:
            val = dict.get(p)
            if val is None:
                raise rhnFault(4007, "No content sent for `%s'" % p)

        log_debug(4, "Params sent", dict)
        path = dict['path']

        config_channel_src = dict['config_channel_src']
        revision_src = dict.get('revision_src')
        fsrc = self._get_file_revision(config_channel_src, revision_src, path)

        config_channel_dst = dict.get('config_channel_dst')
        if config_channel_dst is None:
            config_channel_dst = config_channel_src
        revision_dst = dict.get('revision_dst')
        fdst = self._get_file_revision(config_channel_dst, revision_dst, path)

        if fsrc['label'] != fdst['label']:
            raise rhnFault(4017,
                           "Path %s  is a %s in channel %s while it is a %s in channel %s"
                           % (path, fsrc['label'],
                              config_channel_src, fdst['label'], config_channel_dst),
                           explain=0)

        if fsrc['label'] == 'symlink':
            if (fsrc["symlink"] != fdst['symlink']) or self.__attributes_differ(fsrc, fdst):
                (first_row, second_row) = self.__header(path, fsrc, config_channel_src, fdst, config_channel_dst)
                first_row += ' target: %s' % fsrc["symlink"]
                second_row += ' target: %s' % fdst["symlink"]
                return first_row + "\n" + second_row + "\n"
            return ""

        diff = difflib.unified_diff(
            fsrc['file_content'], fdst['file_content'], path, path, fsrc['modified'], fdst['modified'], lineterm='')
        try:
            first_row = next(diff)
        except StopIteration:
            return ""

        if not first_row.startswith('---'):
            # Hmm, weird
            return first_row + '\n'.join(list(diff))

        try:
            second_row = next(diff)
        except StopIteration:
            second_row = ''

        if not second_row.startswith('+++'):
            # Hmm, weird
            return second_row + '\n'.join(list(diff))

        (first_row, second_row) = self.__header(path, fsrc, config_channel_src, fdst, config_channel_dst)
        return first_row + "\n" + second_row + '\n' + '\n'.join(list(diff))
Esempio n. 18
0
    def entitle(self, server_id, history, virt_type=None):
        """
        Entitle a server according to the entitlements we have configured.
        """
        log_debug(3, self.entitlements)

        entitle_server = rhnSQL.Procedure("rhn_entitlements.entitle_server")
        # TODO: entitle_server calls can_entitle_server, so we're doing this
        # twice for each successful call. Is it necessary for external error
        # handling or can we ditch it?
        can_entitle_server = rhnSQL.Function(
            "rhn_entitlements.can_entitle_server", rhnSQL.types.NUMBER())

        can_ent = None

        history["entitlement"] = ""

        # Do a quick check to see if both virt entitlements are present. (i.e.
        # activation keys stacked together) If so, give preference to the more
        # powerful virtualization platform and remove the regular virt
        # entitlement from the list.
        found_virt = False
        found_virt_platform = False
        for entitlement in self.entitlements:
            if entitlement[0] == VIRT_ENT_LABEL:
                found_virt = True
            elif entitlement[0] == VIRT_PLATFORM_ENT_LABEL:
                found_virt_platform = True

        for entitlement in self.entitlements:
            if virt_type is not None and entitlement[0] in \
                    (VIRT_ENT_LABEL, VIRT_PLATFORM_ENT_LABEL):
                continue

            # If both virt entitlements are present, skip the least powerful:
            if found_virt and found_virt_platform and entitlement[0] == VIRT_ENT_LABEL:
                log_debug(1, "Virtualization and Virtualization Platform " +
                          "entitlements both present.")
                log_debug(1, "Skipping Virtualization.")
                continue

            try:
                can_ent = can_entitle_server(server_id, entitlement[0])
            except rhnSQL.SQLSchemaError, e:
                can_ent = 0

            try:
                # bugzilla #160077, skip attempting to entitle if we cant
                if can_ent:
                    entitle_server(server_id, entitlement[0])
            except rhnSQL.SQLSchemaError, e:
                log_error("Token failed to entitle server", server_id,
                          self.get_names(), entitlement[0], e.errmsg)
                if e.errno == 20220:
                    # ORA-20220: (servergroup_max_members) - Server group membership
                    # cannot exceed maximum membership
                    raise rhnFault(91,
                                   _("Registration failed: RHN Software service entitlements exhausted: %s") % entitlement[0]), None, sys.exc_info()[2]
                # No idea what error may be here...
                raise rhnFault(90, e.errmsg), None, sys.exc_info()[2]
Esempio n. 19
0
 def __init__(self, dict=None):
     log_debug(4, dict)
     self.ifaces = {}
     self.db_ifaces = []
     # parameters which are not allowed to be empty and set to NULL
     self._autonull = ("hw_addr", "module")
     if not dict:
         return
     for name, info in dict.items():
         if name == "class":
             # Ignore it
             continue
         if not isinstance(info, type({})):
             raise rhnFault(53, "Unexpected format for interface %s" % name)
         vdict = {}
         for key, mapping in self.key_mapping.items():
             # Look at the mapping first; if not found, look for the key
             if mapping in info:
                 k = mapping
             else:
                 k = key
             if k not in info:
                 raise rhnFault(53, "Unable to find required field %s" % key)
             val = info[k]
             vdict[mapping] = val
         if "ipaddr" in info and info["ipaddr"]:
             vdict["ipv4"] = NetIfaceAddress4(
                 [{"ipaddr": info["ipaddr"], "broadcast": info["broadcast"], "netmask": info["netmask"]}]
             )
         if "ipv6" in info and info["ipv6"]:
             vdict["ipv6"] = NetIfaceAddress6(info["ipv6"])
         self.ifaces[name] = vdict
Esempio n. 20
0
def validate_new_password(password):
    """ Perform all the checks required for new passwords """
    log_debug(3, "Entered validate_new_password")
    #
    # We're copying the code because we don't want to
    # invalidate any of the existing passwords.
    #

    # Validate password based on configurable length
    # regular expression
    if not password:
        raise rhnFault(12)
    if len(password) < CFG.MIN_PASSWD_LEN:
        raise rhnFault(14, _("password must be at least %d characters")
                       % CFG.MIN_PASSWD_LEN)
    if len(password) > CFG.MAX_PASSWD_LEN:
        raise rhnFault(701, _("Password must be shorter than %d characters")
                       % CFG.MAX_PASSWD_LEN)

    password = password[:CFG.MAX_PASSWD_LEN]
    invalid_re = re.compile(
        r"[^ A-Za-z0-9`!@#$%^&*()-_=+[{\]}\\|;:'\",<.>/?~]")
    asterisks_re = re.compile(r"^\**$")

    # make sure the password isn't all *'s
    tmp = asterisks_re.match(password)
    if tmp is not None:
        raise rhnFault(15, "password cannot be all asterisks '*'")

    # make sure we have only printable characters
    tmp = invalid_re.search(password)
    if tmp is not None:
        pos = tmp.regs[0]
        raise rhnFault(15,
                       _("password contains character `%s'") % password[pos[1] - 1])
    def _get_file_revision(self, config_channel, revision, path):
        if revision and not revision.isdigit():
            raise rhnFault(4016, "Invalid revision number '%s' specified for path %s "
                           "in channel %s" % (revision, path, config_channel),
                           explain=0)

        f = self._get_file(config_channel, path, revision=revision)
        if not f:
            raise rhnFault(4011, "File %s (revision %s) does not exist "
                           "in channel %s" % (path, revision, config_channel),
                           explain=0)
        if f['label'] == 'file' and f['is_binary'] == 'Y':
            raise rhnFault(4004, "File %s (revision %s) seems to contain "
                           "binary data" % (path, revision),
                           explain=0)

        # We have to read the contents of the first file here, because the LOB
        # object is tied to a cursor; if we re-execute the cursor, the LOB
        # seems to be invalid (bug 151220)

        # Empty files or directories may have NULL instead of lobs
        fc_lob = f.get('file_contents')
        if fc_lob:
            f['file_content'] = rhnSQL.read_lob(fc_lob).splitlines()
        else:
            f['file_content'] = ''
        return f
Esempio n. 22
0
 def _get_item_id(self, prefix, name, errnum, errmsg):
     prefix_len = len(prefix)
     if name[:prefix_len] != prefix:
         raise rhnFault(errnum, errmsg % name)
     try:
         id = int(name[prefix_len:])
     except ValueError:
         raise rhnFault(errnum, errmsg % name), None, sys.exc_info()[2]
     return id
Esempio n. 23
0
 def validate_system_input(self, data):
     """ check the input data """
     if not hash_validate(data, "os_release", "architecture", "profile_name"):
         log_error("Incomplete data hash")
         raise rhnFault(21, _("Required data missing"))
     # we require either a username and a password or a token
     if not hash_validate(data, "username", "password") and \
        not hash_validate(data, "token"):
         raise rhnFault(21, _("Required members missing"))
Esempio n. 24
0
 def _get_item_id(prefix, name, errnum, errmsg):
     prefix_len = len(prefix)
     if name[:prefix_len] != prefix:
         raise rhnFault(errnum, errmsg % name)
     try:
         uuid = int(name[prefix_len:])
     except ValueError:
         raise_with_tb(rhnFault(errnum, errmsg % name), sys.exc_info()[2])
     return uuid
Esempio n. 25
0
def __new_user_db(username, password, email, org_id, org_password):
    encrypted_password = CFG.encrypted_passwords
    log_debug(3, username, email, encrypted_password)

    # now search it in the database
    h = rhnSQL.prepare("""
    select w.id, w.password, ui.use_pam_authentication
    from web_contact w, rhnUserInfo ui
    where w.login_uc = upper(:username)
    and w.id = ui.user_id
    """)
    h.execute(username=username)
    data = h.fetchone_dict()

    pre_existing_user = 0

    if not data:
        # the username is not there, check the reserved user table
        h = rhnSQL.prepare("""
        select login, password from rhnUserReserved
        where login_uc = upper(:username)
        """)
        h.execute(username=username)
        data = h.fetchone_dict()
        if not data:  # nope, not reserved either
            raise rhnFault(1, _("Username `%s' has not been reserved") % username)
    else:
        pre_existing_user = 1

    if not pre_existing_user and not email:
        # New accounts have to specify an e-mail address
        raise rhnFault(30, _("E-mail address not specified"))

    # we have to perform PAM authentication if data has a field called
    # 'use_pam_authentication' and its value is 'Y', and we do have a PAM
    # service set in the config file.
    # Note that if the user is only reserved we don't do PAM authentication
    if data.get('use_pam_authentication') == 'Y' and CFG.pam_auth_service:
        # Check the password with PAM
        import rhnAuthPAM
        if rhnAuthPAM.check_password(username, password, CFG.pam_auth_service) <= 0:
            # Bad password
            raise rhnFault(2)
        # We don't care about the password anymore, replace it with something
        import time
        password = '******' % time.time()
    else:
        # Regular authentication
        if check_password(password, data["password"]) == 0:
            # Bad password
            raise rhnFault(2)

    # creation of user was never supported in spacewalk but this call was mis-used
    # to check username/password in the past
    # so let's skip other checks and return now
    return 0
Esempio n. 26
0
    def _normalize_packages(self, system_id, packages, allow_none=0):
        """ the function checks if list of packages is well formated
            and also converts packages from old list of lists
            (extended_profile >= 2) to new list of dicts (extended_profile = 2)
        """

        if allow_none and packages is None:
                return None
        # we need to be paranoid about the format of the argument because
        # if we accept wrong input then we might end up disposing in error
        # of all packages registered here
        if type(packages) != type([]):
            log_error("Invalid argument type", type(packages))
            raise rhnFault(21)

        # Update the capabilities list
        server = self.auth_system(system_id)
        rhnCapability.update_client_capabilities(self.server_id)

        # old clients send packages as a list of arrays
        # while new (capability packages.extended_profile >= {version: 2, value: 1})
        # use a list of dicts
        client_caps = rhnCapability.get_client_capabilities()
        package_is_dict = 0
        packagesV2 = []
        if client_caps and client_caps.has_key('packages.extended_profile'):
            cap_info = client_caps['packages.extended_profile']
            if cap_info and int(cap_info['version']) >= 2:
                package_is_dict = 1
                packagesV2 = packages

        for package in packages:
            if package_is_dict:
                # extended_profile >= 2
                if type(package) != type({}):
                    log_error("Invalid package spec for extended_profile >= 2",
                         type(package), "len = %d" % len(package))
                    raise rhnFault(21)
            else:
                # extended_profile < 2
                if (type(package) != type([]) or len(package) < 4):
                    log_error("Invalid package spec", type(package),
                          "len = %d" % len(package))
                    raise rhnFault(21)
                else:
                    p = {'name'   : package[0],
                         'version': package[1],
                         'release': package[2],
                         'epoch'  : package[3],
                        }
                    if len(package) > 4:
                        p['arch'] = package[4]
                    if len(package) > 5:
                        p['cookie'] = package[5]
                    packagesV2.append(p)
        return packagesV2
Esempio n. 27
0
    def auth_system(self):
        if CFG.DISABLE_ISS:
            raise rhnFault(2005, _('ISS is disabled on this satellite.'))

        if not rhnSQL.fetchone_dict("select 1 from rhnISSSlave where slave = :hostname and enabled = 'Y'",
                                    hostname=idn_puny_to_unicode(self.remote_hostname)):
            raise rhnFault(2004,
                           _('Server "%s" is not enabled for ISS.')
                           % self.remote_hostname)
        return self.remote_hostname
Esempio n. 28
0
    def headerParserHandler(self, req):
        ret = basePackageUpload.BasePackageUpload.headerParserHandler(self, req)
        # Optional headers
        maps = [['Null-Org', 'null_org'], ['Packaging', 'packaging']]
        for hn, sn in maps:
            header_name = "%s-%s" % (self.header_prefix, hn)
            if req.headers_in.has_key(header_name):
                setattr(self, sn, req.headers_in[header_name])

        if ret != apache.OK:
            return ret

        if CFG.SEND_MESSAGE_TO_ALL:
            rhnSQL.closeDB()
            log_debug(1, "send_message_to_all is set")

            rhnFlags.set("apache-return-code", apache.HTTP_NOT_FOUND)
            try:
                outage_message = open(CFG.MESSAGE_TO_ALL).read()
            except IOError:
                log_error("Missing outage message file")
                outage_message = "Outage mode"
            raise rhnFault(20001, outage_message, explain=0)

        # Init the database connection
        rhnSQL.initDB()
        use_session = 0
        if self.field_data.has_key('Auth-Session'):
            session_token = self.field_data['Auth-Session']
            use_session = 1
        else:
            encoded_auth_token = self.field_data['Auth']

        if not use_session:
            auth_token = self.get_auth_token(encoded_auth_token)

            if len(auth_token) < 2:
                log_debug(3, auth_token)
                raise rhnFault(105, "Unable to autenticate")

            self.username, self.password = auth_token[:2]

        force = self.field_data['Force']
        force = int(force)
        log_debug(1, "Username", self.username, "Force", force)

        if use_session:
            self.org_id, self.force = rhnPackageUpload.authenticate_session(session_token,
                                                                            force=force, null_org=self.null_org)
        else:
            # We don't push to any channels
            self.org_id, self.force = rhnPackageUpload.authenticate(self.username,
                                                                    self.password, force=force, null_org=self.null_org)

        return apache.OK
Esempio n. 29
0
def check_package_file(rel_path, logpkg, raisepkg):
    if rel_path is None:
        log_error("Package path null for package id", logpkg)
        raise rhnFault(17, _("Invalid RPM package %s requested") % raisepkg)
    filePath = "%s/%s" % (CFG.MOUNT_POINT, rel_path)
    if not os.access(filePath, os.R_OK):
        # Package not found on the filesystem
        log_error("Package not found", filePath)
        raise rhnFault(17, _("Package not found"))

    return filePath
Esempio n. 30
0
def auth_username_password(username, password):
    # hrm.  it'd be nice to move importlib.userAuth stuff here
    user = search(username)

    if not user:
        raise rhnFault(2, _("Invalid username/password combination"))

    if not user.check_password(password):
        raise rhnFault(2, _("Invalid username/password combination"))

    return user
Esempio n. 31
0
    def _validate_channels(self, channel_labels=None):
        log_debug(4)
        # Sanity check
        if channel_labels:
            if not isinstance(channel_labels, ListType):
                raise rhnFault(3000,
                               "Expected list of channels, got %s" % type(channel_labels))

        h = self.get_channels_statement()
        h.execute()
        # Hash the list of all available channels based on the label
        all_channels_hash = {}
        while 1:
            row = h.fetchone_dict()
            if not row:
                break
            all_channels_hash[row['label']] = row

        # Intersect the list of channels they've sent to us
        iss_slave_sha256_capable = (float(rhnFlags.get('X-RHN-Satellite-XML-Dump-Version'))
                                    >= constants.SHA256_SUPPORTED_VERSION)

        if not channel_labels:
            channels = all_channels_hash
        else:
            channels = {}
            for label in channel_labels:
                if label not in all_channels_hash:
                    raise rhnFault(3001, "Could not retrieve channel %s" %
                                   label)
                if not (iss_slave_sha256_capable
                        or all_channels_hash[label]['checksum_type'] in [None, 'sha1']):
                    raise rhnFault(3001,
                                   ("Channel %s has incompatible rpm checksum (%s). Please contact\n"
                                    + "Red Hat support for information about upgrade to newer version\n"
                                    + "of Satellite Server which supports it.") %
                                   (label, all_channels_hash[label]['checksum_type']))
                channels[label] = all_channels_hash[label]

        return channels
Esempio n. 32
0
    def _serverCommo(self):
        """ Handler part 2

            Server (or next proxy) communication.
        """

        log_debug(1)

        # Copy the method from the original request, and use the
        # handler for this server
        # We add path_info to the put (GET, CONNECT, HEAD, PUT, POST) request.
        log_debug(2, self.req.method, self.uri)
        self.responseContext.getConnection().putrequest(self.req.method,
                                                        self.uri)

        # Send the headers, the body and expect a response
        try:
            status, headers, bodyFd = self._proxy2server()
            self.responseContext.setHeaders(headers)
            self.responseContext.setBodyFd(bodyFd)
        except IOError:
            # Raised by HTTP*Connection.getresponse
            # Server closed connection on us, no need to mail out
            # XXX: why are we not mailing this out???
            Traceback("SharedHandler._serverCommo", self.req, mail=0)
            raise_with_tb(rhnFault(1000, _(
                "SUSE Manager Proxy error: connection with the SUSE Manager server failed")), sys.exc_info()[2])
        except socket.error: # pylint: disable=duplicate-except
            # maybe self.req.read() failed?
            Traceback("SharedHandler._serverCommo", self.req)
            raise_with_tb(rhnFault(1000, _(
                "SUSE Manager Proxy error: connection with the SUSE Manager server failed")), sys.exc_info()[2])

        log_debug(2, "HTTP status code (200 means all is well): %s" % status)

        # Now we need to decide how to deal with the server's response.  We'll
        # defer to subclass-specific implementation here.  The handler will
        # return apache.OK if the request was a success.

        return self._handleServerResponse(status)
Esempio n. 33
0
    def _repodata_taskomatic(self, file_name):
        log_debug(3, 'repodata', file_name)

        content_type = "application/x-gzip"

        if file_name in ["repomd.xml", "comps.xml", "products.xml"]:
            content_type = "text/xml"
        elif file_name in ["repomd.xml.asc", "repomd.xml.key"]:
            content_type = "text/plain"
        elif file_name not in [
                "primary.xml.gz", "other.xml.gz", "filelists.xml.gz",
                "updateinfo.xml.gz", "Packages.gz", "modules.yaml",
                "InRelease", "Release", "Release.gpg", "susedata.xml.gz"
        ]:
            log_debug(2, "Unknown repomd file requested: %s" % file_name)
            raise rhnFault(6)

        # XXX this won't be repconned or CDNd
        if file_name in ["comps.xml", "modules.yaml"]:
            return self._repodata_python(file_name)

        file_path = "%s/%s/%s" % (CFG.REPOMD_PATH_PREFIX, self.channelName,
                                  file_name)
        rhnFlags.set('Content-Type', content_type)
        try:
            rhnFlags.set('Download-Accelerator-Path', file_path)
            return self._getFile(CFG.REPOMD_CACHE_MOUNT_POINT + "/" +
                                 file_path)
        except IOError:
            e = sys.exc_info()[1]
            # For file not found, queue up a regen, and return 404
            if e.errno == 2 and file_name != "comps.xml" and file_name != "modules.yaml":
                taskomatic.add_to_repodata_queue(self.channelName,
                                                 "repodata request",
                                                 file_name,
                                                 bypass_filters=True)
                rhnSQL.commit()
                # This returns 404 to the client
                raise_with_tb(rhnFault(6), sys.exc_info()[2])
            raise
Esempio n. 34
0
def parseRPMFilename(pkgFilename):
    """
    IN: Package Name: xxx-yyy-ver.ver.ver-rel.rel_rel:e.ARCH.rpm (string)
    Understood rules:
       o Name can have nearly any char, but end in a - (well seperated by).
         Any character; may include - as well.
       o Version cannot have a -, but ends in one.
       o Release should be an actual number, and can't have any -'s.
       o Release can include the Epoch, e.g.: 2:4 (4 is the epoch)
       o Epoch: Can include anything except a - and the : seperator???
         XXX: Is epoch info above correct?
    OUT: [n,e,v,r, arch].
    """
    if type(pkgFilename) != type(''):
        raise rhnFault(21, str(pkgFilename))  # Invalid arg.

    pkgFilename = os.path.basename(pkgFilename)

    # Check that this is a package NAME (with arch.rpm) and strip
    # that crap off.
    pkg = string.split(pkgFilename, '.')

    # 'rpm' at end?
    if string.lower(pkg[-1]) not in ['rpm', 'deb']:
        raise rhnFault(
            21, 'neither an rpm nor a deb package name: %s' % pkgFilename)

    # Valid architecture next?
    if check_package_arch(pkg[-2]) is None:
        raise rhnFault(21, 'Incompatible architecture found: %s' % pkg[-2])

    _arch = pkg[-2]

    # Nuke that arch.rpm.
    pkg = string.join(pkg[:-2], '.')
    ret = list(parseRPMName(pkg))
    if ret:
        ret.append(_arch)
    return ret
Esempio n. 35
0
def validate_new_password(password):
    """ Perform all the checks required for new passwords """
    log_debug(3, "Entered validate_new_password")
    #
    # We're copying the code because we don't want to
    # invalidate any of the existing passwords.
    #

    # Validate password based on configurable length
    # regular expression
    if not password:
        raise rhnFault(12)
    if len(password) < CFG.MIN_PASSWD_LEN:
        raise rhnFault(
            14,
            _("password must be at least %d characters") % CFG.MIN_PASSWD_LEN)
    if len(password) > CFG.MAX_PASSWD_LEN:
        raise rhnFault(
            701,
            _("Password must be shorter than %d characters") %
            CFG.MAX_PASSWD_LEN)

    password = password[:CFG.MAX_PASSWD_LEN]
    invalid_re = re.compile(
        r"[^ A-Za-z0-9`!@#$%^&*()-_=+[{\]}\\|;:'\",<.>/?~]")
    asterisks_re = re.compile(r"^\**$")

    # make sure the password isn't all *'s
    tmp = asterisks_re.match(password)
    if tmp is not None:
        raise rhnFault(15, "password cannot be all asterisks '*'")

    # make sure we have only printable characters
    tmp = invalid_re.search(password)
    if tmp is not None:
        pos = tmp.regs[0]
        raise rhnFault(
            15,
            _("password contains character `%s'") % password[pos[1] - 1])
Esempio n. 36
0
    def authzOrg(self, info):
        # This function is a lot more complicated than it should be; the
        # corner case is pushes without a channel; we have to deny regular
        # users the ability to push to their org.

        # If the org id is not specified, default to the user's org id
        if 'orgId' not in info:
            info['orgId'] = self.org_id
        log_debug(4, "info[orgId]", info['orgId'], "org id", self.org_id)

        org_id = info['orgId']

        if org_id == '':
            # Satellites are not allowwd to push in the null org
            raise rhnFault(4,
                           _("You are not authorized to manage packages in the null org"))

        if org_id and self.org_id != org_id:
            # Not so fast...
            raise rhnFault(32,
                           _("You are not allowed to manage packages in the %s org") %
                           org_id)

        # Org admins and channel admins have full privileges; we could use
        # user_manages_channes, except for the case where there are no chanels

        if self.isOrgAdmin() or self.isChannelAdmin():
            log_debug(4, "Org authorized (org_admin or channel_admin)")
            return

        # regular user at this point... check if the user manages any channels
        if user_manages_channels(self.user_id):
            log_debug(4, "Org authorized (user manages a channel)")
            return

        # ok, you're a regular user who doesn't manage any channels.
        # take a hike.
        raise rhnFault(32,
                       _("You are not allowed to perform administrative tasks"))
Esempio n. 37
0
    def get_package_path_by_filename(self, fileName, channel):
        log_debug(3, fileName, channel)
        fileName = str(fileName)
        n, e, v, r, a = rhnLib.parseRPMFilename(fileName)

        h = rhnSQL.prepare(self._query_get_package_path_by_nvra)
        h.execute(name=n, version=v, release=r, epoch=e, arch=a, channel=channel)
        try:
            return _get_path_from_cursor(h)
        except InvalidPackageError:
            log_debug(4, "Error", "Non-existent package requested", fileName)
            raise_with_tb(rhnFault(17, _("Invalid RPM package %s requested") % fileName), sys.exc_info()[2])
        except NullPathPackageError:
            e = sys.exc_info()[1]
            package_id = e[0]
            log_error("Package path null for package id", package_id)
            raise_with_tb(rhnFault(17, _("Invalid RPM package %s requested") % fileName), sys.exc_info()[2])
        except MissingPackageError:
            e = sys.exc_info()[1]
            filePath = e[0]
            log_error("Package not found", filePath)
            raise_with_tb(rhnFault(17, _("Package not found")), sys.exc_info()[2])
Esempio n. 38
0
 def get_repomd_file(self, channel, comps_type_id):
     comps_query = """
         select relative_filename
         from rhnChannelComps
         where channel_id = (
             select id
             from rhnChannel
             where label = :channel_label
             and comps_type_id = :ctype_id
         )
         order by id desc
     """
     channel_comps_sth = rhnSQL.prepare(comps_query)
     channel_comps_sth.execute(channel_label=channel, ctype_id=comps_type_id)
     row = channel_comps_sth.fetchone_dict()
     if not row:
         raise rhnFault(3015, "No comps/modules file for channel [%s]" % channel)
     path = os.path.join(CFG.MOUNT_POINT, row['relative_filename'])
     if not os.path.exists(path):
         log_error("Missing comps/modules file [%s] for channel [%s]" % (path, channel))
         raise rhnFault(3016, "Unable to retrieve comps/modules file for channel [%s]" % channel)
     return self._send_stream(path)
    def auth_system(self, system_id):
        log_debug(3)

        server = rhnServer.get(system_id, load_user=self.load_user)
        if not server:
            # Invalid server certificate.
            raise rhnFault(9,
                           _("Please run rhn_register as root on this client"))
        self.server_id = server.getid()
        self.server = server
        # update the latest checkin time
        if self.update_checkin:
            server.checkin()

        # is the server entitled?
        if self.check_entitlement:
            entitlements = server.check_entitlement()
            if not entitlements:  # we require entitlement for this functionality
                log_error("Server Not Entitled", self.server_id)
                raise rhnFault(
                    31,
                    _('Service not enabled for system profile: "%s"') %
                    server.server["name"])

        # Kind of poking where we shouldn't, but what the hell
        if self.load_user and self.user is not None:
            self.user = server.user.username
        else:
            self.user = None

        if self.user is None:
            self.user = ""
        # Throttle users if necessary
        if self.throttle:
            server.throttle()
        # Set QOS
        if self.set_qos:
            server.set_qos()
        return server
Esempio n. 40
0
def _authenticate(authobj, channels, null_org, force):
    params = {}
    if null_org:
        params['orgId'] = ''

        # XXX don't allow superusers to force stuff
        if force:
            raise rhnFault(4, "Cannot force push nullorg content", explain=0)

    if force and not CFG.FORCE_PACKAGE_UPLOAD:
        raise rhnFault(55, "Package Upload Failed", explain=0)

    authobj.authzOrg(params)
    if channels:
        authobj.authzChannels(channels)

    if null_org:
        org_id = None
    else:
        org_id = authobj.org_id

    return org_id, force
Esempio n. 41
0
    def push_file(self, config_channel_id, file):
        try:
            result = self._push_file(config_channel_id, file)
        except ConfigFilePathIncomplete:
            e = sys.exc_info()[1]
            raise rhnFault(4015,
                           "Full path of file '%s' must be specified" %
                           e.file.get('path'),
                           explain=0).with_traceback(sys.exc_info()[2])
        except ConfigFileExistsError:
            e = sys.exc_info()[1]
            raise rhnFault(4013,
                           "File %s already uploaded" % e.file.get('path'),
                           explain=0).with_traceback(sys.exc_info()[2])
        except ConfigFileVersionMismatchError:
            e = sys.exc_info()[1]
            raise_with_tb(
                rhnFault(4012,
                         "File %s uploaded with a different "
                         "version" % e.file.get('path'),
                         explain=0),
                sys.exc_info()[2])
        except ConfigFileMissingDelimError:
            e = sys.exc_info()[1]
            raise_with_tb(
                rhnFault(4008,
                         "Delimiter not specified for file %s" %
                         e.file.get('path'),
                         explain=0),
                sys.exc_info()[2])
        except ConfigFileMissingContentError:
            e = sys.exc_info()[1]
            raise_with_tb(
                rhnFault(4007,
                         "No content sent for file %s" % e.file.get('path'),
                         explain=0),
                sys.exc_info()[2])
        except ConfigFileExceedsQuota:
            e = sys.exc_info()[1]
            raise_with_tb(
                rhnFault(4014,
                         "File size of %s exceeds free quota space" %
                         e.file.get('path'),
                         explain=0),
                sys.exc_info()[2])
        except ConfigFileTooLargeError:
            e = sys.exc_info()[1]
            raise rhnFault(4003,
                           "File size of %s larger than %s bytes" %
                           (e.file.get('path'), self._get_maximum_file_size()),
                           explain=0).with_traceback(sys.exc_info()[2])

        rhnSQL.commit()
        return result
Esempio n. 42
0
def session_reload(session_string):
    log_debug(4, session_string)
    session = rhnSession.load(session_string)
    web_user_id = session.uid
    if not web_user_id:
        raise rhnSession.InvalidSessionError("No user associated with session")

    u = User("", "")
    ret = u.reload(web_user_id)
    if ret != 0:
        # Something horked
        raise rhnFault(10)
    return u
Esempio n. 43
0
def search(user):
    """ search the database for a user """
    log_debug(3, user)
    userid = get_user_id(user)
    if not userid or is_user_disabled(user):
        # no user found or is disabled
        return None
    ret = User(user, "")
    if not ret.reload(userid) == 0:
        # something horked during reloading entry from database
        # we can not realy say that the entry does not exist...
        raise rhnFault(10)
    return ret
Esempio n. 44
0
    def auth_system(self, req):
        if CFG.DISABLE_ISS:
            raise rhnFault(2005, _('ISS is disabled on this satellite.'))

        remote_hostname = req.get_remote_host(apache.REMOTE_DOUBLE_REV)
        row = rhnSQL.fetchone_dict(
            """
        select id, allow_all_orgs
          from rhnISSSlave
         where slave = :hostname
           and enabled = 'Y'
        """,
            hostname=idn_puny_to_unicode(remote_hostname))
        if not row:
            raise rhnFault(
                2004,
                _('Server "%s" is not enabled for ISS.') % remote_hostname)
        iss_slave_condition = "select id from web_customer"
        if not (row['allow_all_orgs'] == 'Y'):
            iss_slave_condition = "select rhnISSSlaveOrgs.org_id from rhnISSSlaveOrgs where slave_id = %d" % row[
                'id']
        return iss_slave_condition
Esempio n. 45
0
    def getTinyUrlChannel(self, tinyurl, system_id):
        """ Gets channel information for this tinyurl"""
        log_debug(5, tinyurl)
        # authenticate that this request is initiated from a proxy
        self.auth_system(system_id)
        ret = rhnChannel.getChannelInfoForTinyUrl(tinyurl)
        if not ret or not 'url' in ret or len(ret['url'].split('/')) != 6:
            raise rhnFault(
                40, "could not find any data on tiny url '%s'" % tinyurl)

        # tiny urls are always for kickstart sessions
        args = ret['url'].split('/')
        return self.__getKickstartSessionChannel(args[-1], args[-2])
Esempio n. 46
0
    def __processSystemid(self):
        """ update the systemid/serverid but only if they stat differently.
            returns 0=no updates made; or 1=updates were made
        """
        if not os.access(ProxyAuth.__systemid_filename, os.R_OK):
            log_error("unable to access %s" % ProxyAuth.__systemid_filename)
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (Spacewalk Proxy systemid has wrong permissions?). "
                  "Please contact your system administrator."))

        mtime = None
        try:
            mtime = os.stat(ProxyAuth.__systemid_filename)[-2]
        except IOError, e:
            log_error("unable to stat %s: %s" %
                      (ProxyAuth.__systemid_filename, repr(e)))
            raise rhnFault(
                1000,
                _("Spacewalk Proxy error (Spacewalk Proxy systemid has wrong permissions?). "
                  "Please contact your system administrator.")
            ), None, sys.exc_info()[2]
Esempio n. 47
0
    def _connectToParent(self):
        """ Handler part 1
            Should not return an error code -- simply connects.
        """

        scheme, host, port, self.uri, query = self._parse_url(self.rhnParent)
        self.responseContext.setConnection(self._create_connection())

        if not self.uri:
            self.uri = '/'

        # if this request is for an upstream server, use the original query string.
        # Otherwise, if it is for the local Squid instance, strip it so that
        # Squid will not keep multiple cached copies of the same resource
        if self.httpProxy not in ['127.0.0.1:8080', 'localhost:8080']:
            if 'X-Suse-Auth-Token' in self.req.headers_in:
                self.uri += '?%s' % self.req.headers_in['X-Suse-Auth-Token']
            elif query:
                self.uri += '?%s' % query

        log_debug(3, 'Scheme:', scheme)
        log_debug(3, 'Host:', host)
        log_debug(3, 'Port:', port)
        log_debug(3, 'URI:', self.uri)
        log_debug(3, 'HTTP proxy:', self.httpProxy)
        log_debug(3, 'HTTP proxy username:'******'HTTP proxy password:'******'CA cert:', self.caChain)

        try:
            self.responseContext.getConnection().connect()
        except socket.error as e:
            log_error("Error opening connection", self.rhnParent, e)
            Traceback(mail=0)
            raise rhnFault(1000,
                           _("SUSE Manager Proxy could not successfully connect its SUSE Manager parent. "
                             "Please contact your system administrator.")), None, sys.exc_info()[2]

        # At this point the server should be okay
        log_debug(3, "Connected to parent: %s " % self.rhnParent)
        if self.httpProxy:
            if self.httpProxyUsername:
                log_debug(3, "HTTP proxy info: %s %s/<password>" % (
                    self.httpProxy, self.httpProxyUsername))
            else:
                log_debug(3, "HTTP proxy info: %s" % self.httpProxy)
        else:
            log_debug(3, "HTTP proxy info: not using an HTTP proxy")
        peer = self.responseContext.getConnection().sock.getpeername()
        log_debug(4, "Other connection info: %s:%s%s" %
                  (peer[0], peer[1], self.uri))
Esempio n. 48
0
class ProxyAuth:

    __serverid = None
    __systemid = None
    __systemid_mtime = None
    __systemid_filename = UP2DATE_CONFIG['systemIdPath']

    __nRetries = 3  # number of login retries

    hostname = None

    def __init__(self, hostname):
        log_debug(3)
        ProxyAuth.hostname = hostname
        self.__processSystemid()

    def __processSystemid(self):
        """ update the systemid/serverid but only if they stat differently.
            returns 0=no updates made; or 1=updates were made
        """
        if not os.access(ProxyAuth.__systemid_filename, os.R_OK):
            log_error("unable to access %s" % ProxyAuth.__systemid_filename)
            raise rhnFault(1000,
                           _("Spacewalk Proxy error (Spacewalk Proxy systemid has wrong permissions?). "
                             "Please contact your system administrator."))

        mtime = None
        try:
            mtime = os.stat(ProxyAuth.__systemid_filename)[-2]
        except IOError, e:
            log_error("unable to stat %s: %s" % (ProxyAuth.__systemid_filename, repr(e)))
            raise rhnFault(1000,
                           _("Spacewalk Proxy error (Spacewalk Proxy systemid has wrong permissions?). "
                             "Please contact your system administrator.")), None, sys.exc_info()[2]

        if not self.__systemid_mtime:
            ProxyAuth.__systemid_mtime = mtime

        if self.__systemid_mtime == mtime \
                and self.__systemid and self.__serverid:
            # nothing to do
            return 0

        # get systemid
        try:
            ProxyAuth.__systemid = open(ProxyAuth.__systemid_filename, 'r').read()
        except IOError, e:
            log_error("unable to read %s" % ProxyAuth.__systemid_filename)
            raise rhnFault(1000,
                           _("Spacewalk Proxy error (Spacewalk Proxy systemid has wrong permissions?). "
                             "Please contact your system administrator.")), None, sys.exc_info()[2]
Esempio n. 49
0
 def __init__(self, dict=None):
     log_debug(4, dict)
     self.ifaces = {}
     self.db_ifaces = []
     # parameters which are not allowed to be empty and set to NULL
     self._autonull = ('hw_addr', 'module')
     if not dict:
         return
     for name, info in list(dict.items()):
         if name == 'class':
             # Ignore it
             continue
         if not isinstance(info, type({})):
             raise rhnFault(53, "Unexpected format for interface %s" % name)
         vdict = {}
         for key, mapping in list(self.key_mapping.items()):
             # Look at the mapping first; if not found, look for the key
             if mapping in info:
                 k = mapping
             else:
                 k = key
             if k not in info:
                 raise rhnFault(53,
                                "Unable to find required field %s" % key)
             val = info[k]
             vdict[mapping] = val
         if 'ipaddr' in info and info['ipaddr']:
             vdict['ipv4'] = NetIfaceAddress4([{
                 'ipaddr':
                 info['ipaddr'],
                 'broadcast':
                 info['broadcast'],
                 'netmask':
                 info['netmask']
             }])
         if 'ipv6' in info and info['ipv6']:
             vdict['ipv6'] = NetIfaceAddress6(info["ipv6"])
         self.ifaces[name] = vdict
Esempio n. 50
0
 def __solveDep_prepare(self, system_id, deps, action, clientVersion):
     """ Response for clients:
             version 1: list
             version 2: hash
     """
     log_debug(7, system_id, deps, action, clientVersion)
     faultString = _("Invalid value %s (%s)")
     if type(deps) not in (ListType, TupleType):
         log_error("Invalid argument type", type(deps))
         raise rhnFault(30, faultString % (deps, type(deps)))
     for dep in deps:
         if type(dep) is not StringType:
             log_error("Invalid dependency member", type(dep))
             raise rhnFault(30, faultString % (dep, type(dep)))
     # Ignore empty strings
     deps = list(filter(len, deps))
     # anything left to do?
     if not deps:
         return []
     # Authenticate the system certificate
     server = self.auth_system(action, system_id)
     log_debug(1, self.server_id, action, "items: %d" % len(deps))
     return deps
Esempio n. 51
0
def check_email(email):
    """ Do some minimal checks on the e-mail address """
    if email is not None:
        email = email.strip()

    if not email:
        # Still supported
        return None

    if len(email) > CFG.MAX_EMAIL_LEN:
        raise rhnFault(100, _("Please limit your e-mail address to %s chars") %
            CFG.MAX_EMAIL_LEN)
    # XXX More to come (check the format is indeed [email protected]
    return email
Esempio n. 52
0
def load_package(package_stream):
    if package_stream.name.endswith('.deb'):
        try:
            header, payload_stream = rhn_deb.load(filename=package_stream.name)
        except:
            raise_with_tb(rhnFault(50, "Unable to load package", explain=0),
                          sys.exc_info()[2])
    else:
        try:
            header, payload_stream = rhn_mpm.load(file=package_stream)
        except:
            raise_with_tb(rhnFault(50, "Unable to load package", explain=0),
                          sys.exc_info()[2])

    payload_stream.seek(0, 0)
    if header.packaging == "mpm" or header.packaging == "deb":
        header.header_start = header.header_end = 0
        (header_start, header_end) = (0, 0)
    else:
        (header_start, header_end) = get_header_byte_range(payload_stream)
        payload_stream.seek(0, 0)

    return header, payload_stream, header_start, header_end
Esempio n. 53
0
    def management_remove_channel(self, dict):
        log_debug(1)
        self._get_and_validate_session(dict)

        config_channel = dict.get('config_channel')
        # XXX Validate the namespace

        row = rhnSQL.fetchone_dict(self._query_config_channel_by_label,
                  org_id=self.org_id, label=config_channel)

        if not row:
            raise rhnFault(4009, "Channel not found")

        delete_call = rhnSQL.Procedure('rhn_config.delete_channel')

        try:
            delete_call(row['id'])
        except rhnSQL.SQLError, e:
            errno = e.args[0]
            if errno == 2292:
                raise rhnFault(4005, "Cannot remove non-empty channel %s" %
                    config_channel, explain=0), None, sys.exc_info()[2]
            raise
Esempio n. 54
0
def getUserGroups(login, password):
    # Authenticates a user and returns the list of groups it belongs
    # to, and the org id
    add_to_seclist(password)
    log_debug(4, login)
    user = rhnUser.search(login)

    if not user:
        log_debug("rhnUser.search failed")
        raise rhnFault(2)

    # Check the user's password
    if not user.check_password(password):
        log_debug("user.check_password failed")
        raise rhnFault(2)

    if rhnUser.is_user_disabled(username):
        msg = _("""
               %s Account has been deactivated on this server.
               Please contact your Org administrator for more help.""")
        raise rhnFault(1, msg % username, explain=0)

    return getUserGroupsFromUserInstance(user)
Esempio n. 55
0
    def upload_result(self, system_id, action_id, scap_file):
        self.auth_system(system_id)
        self._authorize_request(action_id)

        required_keys = ['filename', 'filecontent', 'content-encoding']
        for k in required_keys:
            if k not in scap_file:
                log_debug(
                    1, self.server_id,
                    "The scap file data is invalid or incomplete: %s" %
                    scap_file)
                raise rhnFault(5101, "Missing or invalid key: %s" % k)

        return self._store_file(action_id, scap_file)
Esempio n. 56
0
 def upgrade_version(self, system_id, newver):
     """ Upgrade a certificate's version to a different release. """
     log_debug(5, system_id, newver)
     # we need to load the user because we will generate a new certificate
     self.load_user = 1
     server = self.auth_system(system_id)
     newver = str(newver)
     if not newver:
         raise rhnFault(21, _("Invalid system release version requested"))
     #log the entry
     log_debug(1, server.getid(), newver)
     ret = server.change_base_channel(newver)
     server.save()
     return server.system_id()
Esempio n. 57
0
 def subscribeChannels(self, system_id, channelNames, username, passwd):
     """ Clients v2+ """
     log_debug(5, system_id, channelNames, username, passwd)
     # Authenticate the system certificate
     self.auth_system('subscribeChannel', system_id)
     # log the entry
     log_debug(1, self.server_id, channelNames)
     server_lib.snapshot_server(self.server_id, 'Base Channel Updated')
     for channelName in channelNames:
         if NONSUBSCRIBABLE_CHANNELS.search(channelName):
             raise rhnFault(73, explain=False)
         else:
             rhnChannel.subscribe_channel(self.server_id, channelName,
                                          username, passwd)
     return 0
Esempio n. 58
0
def listPackages(server, channel, version):
    """ Generates a list of objects by calling the function """

    try:
        return server.listAllPackagesChecksum(channel, version)
    # pylint: disable=W0702
    except:
        try:
            return server.listAllPackages(channel, version)
        except xmlrpclib.ProtocolError, e:
            errcode, errmsg = rpclib.reportError(e.headers)
            raise rhnFault(
                1000, "SpacewalkProxy error (xmlrpclib.ProtocolError): "
                "errode=%s; errmsg=%s" %
                (errcode, errmsg)), None, sys.exc_info()[2]
Esempio n. 59
0
    def _get_method_params(self):
        # Returns the method name and params for this call

        # Split the request into parts
        array = self.req.path_info.split('/')
        if len(array) < 4:
            log_error("Invalid URI for GET request", self.req.path_info)
            raise rhnFault(21, _("Invalid URI %s" % self.req.path_info))

        self.channel, method = (array[2], array[3])
        if method == "getPackage":
            params = tuple([os.path.join(*array[4:])])
        else:
            params = tuple(array[4:])
        return method, params
Esempio n. 60
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