/usr/share/rhn/up2date_client/rhnreg.py is in rhn-client-tools 1.8.26-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | #
# RHN Registration Client
# Copyright (c) 2000--2012 Red Hat, Inc.
#
# Authors:
# Adrian Likins <alikins@redhat.com>
# Preston Brown <pbrown@redhat.com>
# Daniel Benamy <dbenamy@redhat.com>
import os
import sys
import dbus
import up2dateUtils
import up2dateErrors
import rhnserver
import pkgUtils
import up2dateLog
import urlparse
import rhnreg_constants
import hardware
from rhnPackageInfo import convertPackagesFromHashToList
from types import ListType, TupleType, StringType, UnicodeType, DictType, DictionaryType
from pkgplatform import getPlatform
import xmlrpclib
try:
from virtualization import support
except ImportError:
support = None
import gettext
t = gettext.translation('rhn-client-tools', fallback=True)
_ = t.ugettext
# global variables
#SYSID_DIR = /tmp
SYSID_DIR = "/etc/sysconfig/rhn"
REMIND_FILE = "%s/rhn_register_remind" % SYSID_DIR
HW_CODE_FILE = "%s/hw-activation-code" % SYSID_DIR
RHSM_FILE = "/etc/pki/consumer/cert.pem"
import config
cfg = config.initUp2dateConfig()
log = up2dateLog.initLog()
def startRhnsd():
# successful registration. Try to start rhnsd if it isn't running.
if os.access("/usr/sbin/rhnsd", os.R_OK|os.X_OK):
if os.access("/sbin/chkconfig", os.R_OK|os.X_OK):
os.system("/sbin/chkconfig rhnsd on > /dev/null");
else:
print _("Warning: unable to enable rhnsd with chkconfig")
service_path = "/sbin/service"
if not os.access(service_path, os.R_OK|os.X_OK):
if os.access("/usr/sbin/service", os.R_OK|os.X_OK):
service_path = "/usr/sbin/service"
rc = os.system("%s rhnsd status > /dev/null" % service_path)
if rc:
os.system("%s rhnsd start > /dev/null" % service_path)
def getOemInfo():
configFile = cfg["oemInfoFile"] or "/etc/sysconfig/rhn/oeminfo"
if not os.access(configFile, os.R_OK):
return {}
fd = open(configFile, "r")
L = fd.readlines()
info = {}
for i in L:
i = i.strip()
if i == "":
continue
try:
(key, value) = i.split(':')
except ValueError:
raise up2dateErrors.OemInfoFileError(i), None, sys.exc_info()[2]
info[key] = value.strip()
return info
def rhsm_registered():
""" Returns true if system is registred using subscription manager """
if os.access(RHSM_FILE, os.R_OK):
statinfo = os.stat(RHSM_FILE)
return statinfo.st_size > 0
else:
return False
def registered():
return os.access(cfg['systemIdPath'], os.R_OK)
def createSystemRegisterRemindFile():
if not os.access(REMIND_FILE, os.R_OK):
# touch the file to tell the applet it needs to remind
# the user to register
fd = open(REMIND_FILE, "w+")
fd.close()
def removeSystemRegisterRemindFile():
if os.access(REMIND_FILE, os.R_OK):
os.unlink(REMIND_FILE)
def _write_secure_file(secure_file, file_contents):
""" Write a file to disk that is not readable by other users. """
dir_name = os.path.dirname(secure_file)
if not os.access(dir_name, os.W_OK):
return False
if os.access(secure_file, os.F_OK):
# already have file there; let's back it up
try:
os.rename(secure_file, secure_file + '.save')
except:
return False
fd = os.open(secure_file, os.O_WRONLY | os.O_CREAT, 0600)
fd_file = os.fdopen(fd, 'w')
try:
fd_file.write(file_contents)
finally:
fd_file.close()
return True
def writeSystemId(systemId):
res = _write_secure_file(cfg['systemIdPath'], systemId)
# newer registratio clients will create a file indicating that
# we need to remind the user to register, this removes it
if res:
removeSystemRegisterRemindFile()
updateRhsmStatus()
return res
def writeHWCode(hw_activation_code):
"""Returns True if the write is successful or False if it fails."""
return _write_secure_file(HW_CODE_FILE, hw_activation_code + '\n')
def get_virt_info():
"""
This function returns the UUID and virtualization type of this system, if
it is a guest. Otherwise, it returns None. To figure this out, we'll
use a number of heuristics (list in order of precedence):
1. Check /proc/xen/xsd_port. If exists, we know the system is a
host; exit.
2. Check SMBIOS. If vendor='Xen' and UUID is non-zero, we know the
system is a fully-virt guest; exit.
3. Check /sys/hypervisor/uuid. If exists and is non-zero, we know
the system is a para-virt guest; exit.
4. If non of the above checks worked; we know we have a
non-xen-enabled system; exit.
"""
# First, check whether /proc/xen/xsd_port exists. If so, we know this is
# a host system.
try:
if os.path.exists("/proc/xen/xsd_port"):
# Ok, we know this is *at least* a host system. However, it may
# also be a fully-virt guest. Check for that next. If it is, we'll
# just report that instead since we only support one level of
# virtualization.
(uuid, virt_type) = get_fully_virt_info()
return (uuid, virt_type)
except IOError:
# Failed. Move on to next strategy.
pass
# This is not a virt host system. Check if it's a fully-virt guest.
(uuid, virt_type) = get_fully_virt_info()
if uuid is not None:
return (uuid, virt_type)
# This is not a fully virt guest system. Check if it's a para-virt guest.
(uuid, virt_type) = get_para_virt_info()
if uuid is not None:
return (uuid, virt_type)
# If we got here, we have a system that does not have virtualization
# enabled.
return (None, None)
def get_para_virt_info():
"""
This function checks /sys/hypervisor/uuid to see if the system is a
para-virt guest. It returns a (uuid, virt_type) tuple.
"""
try:
uuid_file = open('/sys/hypervisor/uuid', 'r')
uuid = uuid_file.read()
uuid_file.close()
uuid = uuid.lower().replace('-', '').rstrip("\r\n")
virt_type = "para"
return (uuid, virt_type)
except IOError:
# Failed; must not be para-virt.
pass
return (None, None)
def get_fully_virt_info():
"""
This function looks in the SMBIOS area to determine if this is a
fully-virt guest. It returns a (uuid, virt_type) tuple.
"""
vendor = hardware.dmi_vendor()
uuid = hardware.dmi_system_uuid()
if vendor.lower() == "xen":
uuid = uuid.lower().replace('-', '')
virt_type = "fully"
return (uuid, virt_type)
else:
return (None, None)
def _is_host_uuid(uuid):
uuid = eval('0x%s' % uuid)
return long(uuid) == 0L
def welcomeText():
s = rhnserver.RhnServer()
return s.registration.welcome_message()
def getCaps():
s = rhnserver.RhnServer()
# figure out if were missing any needed caps
s.capabilities.validate()
def reserveUser(username, password):
s = rhnserver.RhnServer()
return s.registration.reserve_user(username, password)
class RegistrationResult:
def __init__(self, systemId, channels, failedChannels, systemSlots,
failedSystemSlots, universalActivationKey, rawDict=None):
# TODO Get rid of rawDict
self._systemId = systemId
self._channels = channels
self._failedChannels = failedChannels
self._systemSlots = systemSlots
self._failedSystemSlots = failedSystemSlots
if len(universalActivationKey) > 0:
self._universalActivationKey = universalActivationKey
else:
self._universalActivationKey = None
self.rawDict = rawDict
def getSystemId(self):
return self._systemId
def getChannels(self):
return self._channels
def getFailedChannels(self):
return self._failedChannels
def getSystemSlots(self):
return self._systemSlots
def getSystemSlotDescriptions(self):
return map(self._getSlotDescription, self._systemSlots)
def getFailedSystemSlotDescriptions(self):
return map(self._getFailedSlotDescription, self._failedSystemSlots)
def getUniversalActivationKey(self):
"""Returns None if no universal activation key was used."""
return self._universalActivationKey
def hasBaseAndUpdates(self):
"""Returns True if the system was subscribed to at least one channel
and was given any type of system slot so it will get updates. In other
words, returns True if the system will be getting at least basic
updates.
"""
# If it was subscribed to at least one channel, that must include a
# base channel.
return len(self._channels) > 0 and len(self._systemSlots) > 0
def _getFailedSlotDescription(self, slot):
if slot in ['virtualization_host', 'virtualization_host_platform']:
return rhnreg_constants.VIRT + " " + rhnreg_constants.VIRT_FAILED
else:
return self._getSlotDescription(slot)
def _getSlotDescription(self, slot):
if slot == 'enterprise_entitled':
return rhnreg_constants.MANAGEMENT
elif slot == 'sw_mgr_entitled':
return rhnreg_constants.UPDATES
elif slot == 'provisioning_entitled':
return rhnreg_constants.PROVISIONING
elif slot == 'monitoring_entitled':
return rhnreg_constants.MONITORING
elif slot == 'virtualization_host':
return rhnreg_constants.VIRT
elif slot == 'virtualization_host_platform':
return rhnreg_constants.VIRT_PLATFORM
else:
return slot
def registerSystem(username = None, password = None,
profileName = None, packages = None,
token = None, other = None):
"""Wrapper for the old xmlrpc to register a system. Activates subscriptions
if a reg num is given.
"""
auth_dict = { "profile_name" : profileName,
"os_release" : up2dateUtils.getVersion(),
"release_name" : up2dateUtils.getOSRelease(),
"architecture" : up2dateUtils.getArch() }
# dict of other bits to send
if other:
for (key, item) in other.items():
auth_dict[key] = item
if token:
auth_dict["token"] = token
else:
auth_dict["username"] = username
auth_dict["password"] = password
if cfg['supportsSMBIOS']:
auth_dict["smbios"] = _encode_characters(hardware.get_smbios())
s = rhnserver.RhnServer()
if packages == None:
ret = s.registration.new_system(auth_dict)
else:
ret = s.registration.new_system(auth_dict, packages)
return ret
def updateRhsmStatus():
try:
bus = dbus.SystemBus()
validity_obj = bus.ProxyObjectClass(bus, 'com.redhat.SubscriptionManager',
'/EntitlementStatus', introspect=False)
validity_iface = dbus.Interface(validity_obj,
dbus_interface='com.redhat.SubscriptionManager.EntitlementStatus')
except dbus.DBusException:
# we can't connect to dbus. it's not running, likely from a minimal
# install. we can't do anything here, so just ignore it.
return
try:
validity_iface.check_status()
except dbus.DBusException:
# the call timed out, or something similar. we don't really care
# about a timely reply or what the result might be, we just want
# the method to run. So we can safely ignore this.
pass
def getAvailableChannels(username, password):
s = rhnserver.RhnServer()
server_arch = up2dateUtils.getArch()
server_version = up2dateUtils.getVersion()
server_release = up2dateUtils.getRelease()
availableChannels = None
try:
availableChannels = s.registration.available_eus_channels(
username, password,
server_arch, server_version,
server_release)
except xmlrpclib.Fault, f:
if f.faultCode == 99:
raise up2dateErrors.DelayError(f.faultString), None, sys.exc_info()[2]
else:
raise
return availableChannels
def registerSystem2(username = None, password = None,
profileName = None, packages = None,
activationKey = None, other = {}):
"""Uses the new xmlrpcs to register a system. Returns a dict instead of just
system id.
The main differences between this and registerSystem and that this doesn't
do activation and does child channel subscriptions if possible. See the
documentation for the xmlrpc handlers in backend for more detail.
If nothing is going to be in other, it can be {} or None.
New in RHEL 5.
"""
if other is None:
other = {}
if activationKey:
assert username is None
assert password is None
assert activationKey is not None
else:
assert username is not None
assert password is not None
assert activationKey is None
for key in other.keys():
assert key in ['registration_number',
'org_id',
'virt_uuid',
'virt_type',
'channel']
if cfg['supportsSMBIOS']:
other["smbios"] = _encode_characters(hardware.get_smbios())
s = rhnserver.RhnServer()
if activationKey:
info = s.registration.new_system_activation_key(profileName,
up2dateUtils.getOSRelease(),
up2dateUtils.getVersion(),
up2dateUtils.getArch(),
activationKey,
other)
else:
info = s.registration.new_system_user_pass(profileName,
up2dateUtils.getOSRelease(),
up2dateUtils.getVersion(),
up2dateUtils.getArch(),
username,
password,
other)
log.log_debug("Returned:\n%s" % info)
result = RegistrationResult(info['system_id'],
info['channels'], info['failed_channels'],
info['system_slots'], info['failed_system_slots'],
info['universal_activation_key'],
rawDict=info)
return result
def server_supports_eus():
return cfg["supportsEUS"]
def sendHardware(systemId, hardwareList):
def remove_ip6addr(x):
if x['class'] == 'NETINFO' and 'ip6addr' in x:
del x['ip6addr']
return x
s = rhnserver.RhnServer()
if not s.capabilities.hasCapability('ipv6', 1):
hardwareList = map(remove_ip6addr, hardwareList)
s.registration.add_hw_profile(systemId, _encode_characters(hardwareList))
def sendPackages(systemId, packageList):
s = rhnserver.RhnServer()
if not s.capabilities.hasCapability('xmlrpc.packages.extended_profile', 2):
# for older satellites and hosted - convert to old format
packageList = convertPackagesFromHashToList(packageList)
s.registration.add_packages(systemId, packageList)
def sendVirtInfo(systemId):
if support is not None:
support.refresh()
def listPackages(systemId):
s = rhnserver.RhnServer()
print s.registration.list_packages,systemId()
def makeNiceServerUrl(server):
"""Raises up2dateErrors.InvalidProtocolError if the server url has a
protocol specified and it's not http or https.
"""
protocol, host, path, parameters, query, fragmentIdentifier = urlparse.urlparse(server)
if protocol is None or protocol == '':
server = 'https://' + server
# We must call it again because if there wasn't a protocol the
# host will be in path
protocol, host, path, parameters, query, fragmentIdentifier = urlparse.urlparse(server)
if protocol not in ['https', 'http']:
raise up2dateErrors.InvalidProtocolError("You specified an invalid "
"protocol. Only https and "
"http are allowed.")
if path is None or path == '' or path == '/':
path = '/XMLRPC'
server = urlparse.urlunparse((protocol, host, path, parameters, query,
fragmentIdentifier))
# TODO Raise an exception if url isn't valid
return server
def getServerType(serverUrl=None):
"""Returns 'hosted' if the url points to a known hosted server. Otherwise
returns 'satellite'.
"""
return 'satellite'
class ActivationResult:
ACTIVATED_NOW = 0
ALREADY_USED = 1
def __init__(self, status, registrationNumber, channels={}, systemSlots={}):
"""channels and systemSlots are dicts where the key/value pairs are
label (string) / quantity (int).
"""
self._status = status
# TODO Validate reg num
self._regNum = registrationNumber
self._channels = channels
self._systemSlots = systemSlots
def getStatus(self):
return self._status
def getRegistrationNumber(self):
return self._regNum
def getChannelsActivated(self):
"""Returns a dict- the key/value pairs are label/quantity."""
return self._channels
def getSystemSlotsActivated(self):
"""Returns a dict- the key/value pairs are label/quantity."""
return self._systemSlots
def _encode_characters(*args):
""" All the data we gathered from dmi, bios, gudev are in utf-8,
we need to convert characters beyond ord(127) - e.g \xae to unicode.
"""
result=[]
for item in args:
item_type = type(item)
if item_type == StringType:
item = unicode(item, 'utf-8')
elif item_type == TupleType:
item = tuple(map(_encode_characters, item))
elif item_type == ListType:
item = map(_encode_characters, item)
elif item_type == DictType or item_type == DictionaryType:
item = dict([(_encode_characters(name, val)) for name, val in item.iteritems()])
# else: numbers or UnicodeType - are safe
result.append(item)
if len(result) == 1:
return result[0]
else:
return tuple(result)
def _activate_hardware(login, password):
# Read the asset code from the hardware.
activateHWResult = None
hardwareInfo = None
hw_activation_code = None
try:
hardwareInfo = hardware.get_hal_system_and_smbios()
hardwareInfo = _encode_characters(hardwareInfo)
except:
log.log_me("There was an error while reading the hardware "
"info from the bios. Traceback:\n")
log.log_exception(*sys.exc_info())
if hardwareInfo is not None:
try:
activateHWResult = activateHardwareInfo(
login, password, hardwareInfo)
if activateHWResult.getStatus() == ActivationResult.ACTIVATED_NOW:
hw_activation_code = activateHWResult.getRegistrationNumber()
writeHWCode(hw_activation_code)
except up2dateErrors.NotEntitlingError:
log.log_debug('There are are no entitlements associated '
'with this hardware.')
except up2dateErrors.InvalidRegistrationNumberError:
log.log_debug('The hardware id was not recognized as valid.')
return hw_activation_code
def activateHardwareInfo(username, password, hardwareInfo, orgId=None):
"""Tries to activate an entitlement linked to the hardware info that we
read from the bios.
Returns an ActivationResult.
Can raise:
Invalid number.
Hardware info is not entitling.
Communication errors, etc
"""
## import pprint
## pprint.pprint(hardwareInfo)
other = {}
if orgId:
other = {'org_id': orgId}
server = rhnserver.RhnServer()
result = server.registration.activate_hardware_info(username, password,
hardwareInfo, other)
statusCode = result['status_code']
regNum = result['registration_number']
log.log_debug('Server returned status code %s' % statusCode)
if statusCode == 0:
return ActivationResult(ActivationResult.ACTIVATED_NOW, regNum)
elif statusCode == 1:
return ActivationResult(ActivationResult.ALREADY_USED, regNum)
else:
message = "The server returned unknown status code %s while activating" \
" the hardware info." % statusCode
raise up2dateErrors.CommunicationError(message)
def spawnRhnCheckForUI():
if os.access("/usr/sbin/rhn_check", os.R_OK|os.X_OK):
from subprocess import Popen, PIPE
p = Popen(["/usr/sbin/rhn_check"], stdin=PIPE, stdout=PIPE, \
stderr=PIPE)
map(lambda x:log.log_me(x), p.stdout.readlines() + \
p.stderr.readlines())
else:
log.log_me("Warning: unable to run rhn_check")
if getPlatform() == 'deb':
def pluginEnable():
"""On Debian no extra action for plugin is needed"""
return 1, 0
else:
from yumPlugin import pluginEnable
|