def _add_proxy_headers(self): if not self.__username: return # Authenticated proxy userpass = "******" % (self.__username, self.__password) enc_userpass = base64.encodestring(i18n.bstr(userpass)).replace(i18n.bstr("\n"), i18n.bstr("")) self.putheader("Proxy-Authorization", "Basic %s" % i18n.sstr(enc_userpass))
def _getOSVersionAndRelease(): osVersionRelease = None ts = transaction.initReadOnlyTransaction() for h in ts.dbMatch('Providename', "oraclelinux-release"): SYSRELVER = 'system-release(releasever)' version = sstr(h['version']) release = sstr(h['release']) if SYSRELVER in h['providename']: provides = dict(zip(h['providename'], h['provideversion'])) release = '%s-%s' % (version, release) version = provides[SYSRELVER] osVersionRelease = (sstr(h['name']), version, release) return osVersionRelease else: for h in ts.dbMatch('Providename', "redhat-release"): SYSRELVER = 'system-release(releasever)' version = sstr(h['version']) release = sstr(h['release']) if SYSRELVER in h['providename']: provides = dict(zip(h['providename'], h['provideversion'])) release = '%s-%s' % (version, release) version = provides[SYSRELVER] osVersionRelease = (sstr(h['name']), version, release) return osVersionRelease else: # new SUSE always has a baseproduct link which point to the # product file of the first installed product (the OS) # all rpms containing a product must provide "product()" # search now for the package providing the base product baseproduct = '/etc/products.d/baseproduct' if os.path.exists(baseproduct): bp = os.path.abspath(os.path.join(os.path.dirname(baseproduct), os.readlink(baseproduct))) for h in ts.dbMatch('Providename', "product()"): if bstr(bp) in h['filenames']: osVersionRelease = (sstr(h['name']), sstr(h['version']), sstr(h['release'])) # zypper requires a exclusive lock on the rpmdb. So we need # to close it here. ts.ts.closeDB() return osVersionRelease else: # for older SUSE versions we need to search for distribution-release # package which also has /etc/SuSE-release file for h in ts.dbMatch('Providename', "distribution-release"): osVersionRelease = (sstr(h['name']), sstr(h['version']), sstr(h['release'])) if bstr('/etc/SuSE-release') in h['filenames']: # zypper requires a exclusive lock on the rpmdb. So we need # to close it here. ts.ts.closeDB() return osVersionRelease raise up2dateErrors.RpmError( "Could not determine what version of Linux you "\ "are running.\nIf you get this error, try running \n\n"\ "\t\trpm --rebuilddb\n\n")
def _read_username(self): tty = open("/dev/tty", "rb+", buffering=0) tty.write(bstr("Username: "******"\n")) sys.exit(0) if username is None: # EOF tty.write(bstr("\n")) sys.exit(0) return username.strip()
def __init__(self, socket, trusted_certs=None): # SSL.Context object self._ctx = None # SSL.Connection object self._connection = None self._sock = socket self._trusted_certs = [] # convert None to empty list trusted_certs = trusted_certs or [] for f in trusted_certs: self.add_trusted_cert(f) # SSL method to use self._ssl_method = SSL.SSLv23_METHOD # Flags to pass to the SSL layer self._ssl_verify_flags = SSL.VERIFY_PEER # Buffer size for reads self._buffer_size = 8192 # Position, for tell() self._pos = 0 # Buffer self._buffer = bstr("") # Flag to show if makefile() was called self._makefile_called = 0 self._closed = None
def init_ssl(self, server_name=None): """ Initializes the SSL connection. """ self._check_closed() # Get a context self._ctx = SSL.Context(self._ssl_method) # disable SSL and allow only TLSv1+ self._ctx.set_options(SSL.OP_NO_SSLv2) self._ctx.set_options(SSL.OP_NO_SSLv3) if self._trusted_certs: # We have been supplied with trusted CA certs for f in self._trusted_certs: self._ctx.load_verify_locations(f) else: # Reset the verify flags self._ssl_verify_flags = 0 self._ctx.set_verify(self._ssl_verify_flags, ssl_verify_callback) if hasattr(SSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS"): # Certain SSL implementations break when empty fragments are # initially sent (even if sending them is compliant to # SSL 3.0 and TLS 1.0 specs). Play it safe and disable this # feature (openssl 0.9.6e and later) self._ctx.set_options(SSL.OP_DONT_INSERT_EMPTY_FRAGMENTS) # Init the connection self._connection = SSL.Connection(self._ctx, self._sock) # Set server name if defined. This allows connections to # SNI-enabled servers if server_name is not None: self._connection.set_tlsext_host_name(bstr(server_name)) # Place the connection in client mode self._connection.set_connect_state()
def getContentChecksum(checksum_type, contents): if hashlib_has_usedforsecurity: engine = hashlib.new(checksum_type, usedforsecurity=False) else: engine = hashlib.new(checksum_type) engine.update(bstr(contents)) return engine.hexdigest()
def idn_puny_to_unicode(hostname): """ Convert Internationalized domain name from Punycode (RFC3492) to Unicode """ if hostname is None: return None else: hostname = i18n.bstr(hostname) return hostname.decode('idna')
def __init__(self, socket, trusted_certs=None): # SSL.Context object self._ctx = None # SSL.Connection object self._connection = None self._sock = socket self._trusted_certs = [] # convert None to empty list trusted_certs = trusted_certs or [] for f in trusted_certs: self.add_trusted_cert(f) # SSL method to use if hasattr(SSL, 'PROTOCOL_TLS'): self._ssl_method = SSL.PROTOCOL_TLS else: self._ssl_method = SSL.PROTOCOL_SSLv23 # Buffer size for reads self._buffer_size = 8192 # Position, for tell() self._pos = 0 # Buffer self._buffer = bstr("") # Flag to show if makefile() was called self._makefile_called = 0 self._closed = None
def send_http(self, host, handler="/RPC2"): if not self.__processed: raise NotProcessed self._host = host if self._connection is None: raise Exception("No connection object found") self._connection.connect() # wrap self data into binary object, otherwise HTTPConnection.request # will encode it as ISO-8859-1 https://docs.python.org/3/library/http.client.html#httpconnection-objects self._connection.request(self.method, handler, body=bstr(self.data), headers=self.headers) response = self._connection.getresponse() if not self.response_acceptable(response): raise xmlrpclib.ProtocolError("%s %s" % (self._host, handler), response.status, response.reason, response.msg) # A response object has read() and close() methods, so we can safely # pass the whole object back return response.msg, response
def _read_bytes(stream, amt): ret = bstr('') while amt: buf = stream.read(min(amt, BUFFER_SIZE)) if not buf: return ret ret = ret + buf amt = amt - len(buf) return ret
def __parse_action_data(self, action): """ Parse action data and returns (method, params) """ data = action['action'] parser, decoder = xmlrpclib.getparser() parser.feed(bstr(data)) parser.close() params = decoder.close() method = decoder.getmethodname() return (method, params)
def xccdf_eval(args, cache_only=None): if cache_only: return (0, 'no-ops for caching', {}) results_dir = None if ('id' in args) and ('file_size' in args) and args['file_size'] > 0: results_dir = tempfile.mkdtemp() pwd = os.getcwd() os.chdir(results_dir) results_file = tempfile.NamedTemporaryFile(dir=results_dir) params, oscap_err = _process_params(args['params'], results_file.name, results_dir) oscap_err += _run_oscap(['xccdf', 'eval'] + params + [args['path']]) if results_dir: os.chdir(pwd) if not _assert_xml(results_file.file): del (results_file) _cleanup_temp(results_dir) return (1, 'oscap tool did not produce valid xml.\n' + oscap_err, {}) ret, resume, xslt_err = _xccdf_resume(results_file.name, temp_dir=results_dir) if ret != 0 or resume == '': del (results_file) _cleanup_temp(results_dir) return (1, 'Problems with extracting resume:\n' + xslt_err, {}) try: up_err = _upload_results(results_file, results_dir, args) except: # An error during the upload must not prevent scan completion log.log_exception(*sys.exc_info()) up_err = "Upload of detailed results failed. Fatal error in Python code occurred" del (results_file) _cleanup_temp(results_dir) return (0, 'openscap scan completed', { 'resume': encodestring(resume), 'errors': encodestring(bstr(oscap_err) + bstr(xslt_err) + bstr(up_err)) })
def process(self, data): # Assume straight text/xml self.data = data # Content-Encoding header if self.encoding == self.ENCODE_GZIP: import gzip encoding_name = self.encodings[self.ENCODE_GZIP][0] self.set_header("Content-Encoding", encoding_name) f = SmartIO(force_mem=1) gz = gzip.GzipFile(mode="wb", compresslevel=COMPRESS_LEVEL, fileobj=f) if sys.version_info[0] == 3: gz.write(bstr(data)) else: gz.write(sstr(data)) gz.close() self.data = f.getvalue() f.close() elif self.encoding == self.ENCODE_ZLIB: import zlib encoding_name = self.encodings[self.ENCODE_ZLIB][0] self.set_header("Content-Encoding", encoding_name) obj = zlib.compressobj(COMPRESS_LEVEL) self.data = obj.compress(data) + obj.flush() elif self.encoding == self.ENCODE_GPG: # XXX: fix me. raise NotImplementedError(self.transfer, self.encoding) encoding_name = self.encodings[self.ENCODE_GPG][0] self.set_header("Content-Encoding", encoding_name) # Content-Transfer-Encoding header if self.transfer == self.TRANSFER_BINARY: transfer_name = self.transfers[self.TRANSFER_BINARY] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "application/binary") elif self.transfer == self.TRANSFER_BASE64: import base64 transfer_name = self.transfers[self.TRANSFER_BASE64] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "text/base64") self.data = base64.encodestring(self.data) self.set_header("Content-Length", len(self.data)) rpc_version = __version__ if len(__version__.split()) > 1: rpc_version = __version__.split()[1] # other headers self.set_header( "X-Transport-Info", "Extended Capabilities Transport (C) Red Hat, Inc (version %s)" % rpc_version ) self.__processed = 1
def process(self, data): # Assume straight text/xml self.data = data # Content-Encoding header if self.encoding == self.ENCODE_GZIP: import gzip encoding_name = self.encodings[self.ENCODE_GZIP][0] self.set_header("Content-Encoding", encoding_name) f = SmartIO(force_mem=1) gz = gzip.GzipFile(mode="wb", compresslevel=COMPRESS_LEVEL, fileobj=f) if sys.version_info[0] == 3: gz.write(bstr(data)) else: gz.write(sstr(data)) gz.close() self.data = f.getvalue() f.close() elif self.encoding == self.ENCODE_ZLIB: import zlib encoding_name = self.encodings[self.ENCODE_ZLIB][0] self.set_header("Content-Encoding", encoding_name) obj = zlib.compressobj(COMPRESS_LEVEL) self.data = obj.compress(data) + obj.flush() elif self.encoding == self.ENCODE_GPG: # XXX: fix me. raise NotImplementedError(self.transfer, self.encoding) encoding_name = self.encodings[self.ENCODE_GPG][0] self.set_header("Content-Encoding", encoding_name) # Content-Transfer-Encoding header if self.transfer == self.TRANSFER_BINARY: transfer_name = self.transfers[self.TRANSFER_BINARY] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "application/binary") elif self.transfer == self.TRANSFER_BASE64: import base64 transfer_name = self.transfers[self.TRANSFER_BASE64] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "text/base64") self.data = base64.encodestring(self.data) self.set_header("Content-Length", len(self.data)) rpc_version = __version__ if len(__version__.split()) > 1: rpc_version = __version__.split()[1] # other headers self.set_header( "X-Transport-Info", 'Extended Capabilities Transport (C) Red Hat, Inc (version %s)' % rpc_version) self.__processed = 1
def _copy_file_to_fd(filename, fd): f = open(filename) buffer_size = 16384 count = 0 while 1: buf = f.read(buffer_size) if not buf: break os.write(fd, bstr(buf)) count = count + len(buf) return count
def sha256_file(filename): engine = hashlib.new('sha256') fh = open(filename, "rb") while 1: buf = fh.read(4096) if not buf: break engine.update(bstr(buf)) return engine.hexdigest()
def xccdf_eval(args, cache_only=None): if cache_only: return (0, 'no-ops for caching', {}) results_dir = None if ('id' in args) and ('file_size' in args) and args['file_size'] > 0: results_dir = tempfile.mkdtemp() pwd = os.getcwd() os.chdir(results_dir) results_file = tempfile.NamedTemporaryFile(dir=results_dir) params, oscap_err = _process_params(args['params'], results_file.name, results_dir) oscap_err += _run_oscap(['xccdf', 'eval'] + params + [args['path']]) if results_dir: os.chdir(pwd) if not _assert_xml(results_file.file): del(results_file) _cleanup_temp(results_dir) return (1, 'oscap tool did not produce valid xml.\n' + oscap_err, {}) ret, resume, xslt_err = _xccdf_resume(results_file.name, temp_dir=results_dir) if ret != 0 or resume == '': del(results_file) _cleanup_temp(results_dir) return (1, 'Problems with extracting resume:\n' + xslt_err, {}) try: up_err = _upload_results(results_file, results_dir, args) except: # An error during the upload must not prevent scan completion log.log_exception(*sys.exc_info()) up_err = "Upload of detailed results failed. Fatal error in Python code occurred" del(results_file) _cleanup_temp(results_dir) return (0, 'openscap scan completed', { 'resume': encodestring(resume), 'errors': encodestring(bstr(oscap_err) + bstr(xslt_err) + bstr(up_err)) })
def diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if 'encoding' in info and info['file_contents']: if info['encoding'] == 'base64': info['file_contents'] = base64.decodestring(bstr(info['file_contents'])) else: die(9, 'Error: unknown encoding %s' % info['encoding']) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink' : die(8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file) : die(8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % (path,src_link, path, dest_link) return "" fromlines = sstr(info['file_contents']).splitlines(1) tolines = open(local_file, 'r').readlines() diff_output = difflib.unified_diff(fromlines, tolines, info['path'], local_file) first_row = second_row = '' try: first_row = next(diff_output) second_row = next(diff_output) except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not 'selinux_ctx' in local_info: local_info['selinux_ctx'] = '' if 'selinux_ctx' not in info: info['selinux_ctx'] = '' if not first_row and not self.__attributes_differ(info, local_info): return "" else: template = "--- %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if 'modified' not in info: info['modified'] = '' first_row = template % (path, str(info['modified']), ostr_to_sym(info['filemode'], info['filetype']), info['username'], info['groupname'], info['selinux_ctx'], channel, info['revision'], ) second_row = template % (local_file, f_date(datetime.fromtimestamp(local_info['mtime'])), ostr_to_sym(local_info['mode'], 'file'), local_info['user'], local_info['group'], local_info['selinux_ctx'], 'local file', None ) return first_row + '\n' + second_row + '\n' + ''.join(list(diff_output))
def read_to_file(self, file): """Copies the contents of this File object into another file object""" fd = self._get_file() while 1: buf = fd.read(self.bufferSize) if not buf: break if sys.version_info[0] == 3: file.write(bstr(buf)) else: file.write(sstr(buf)) return file
def read(self, amt=None): """ Reads up to amt bytes from the SSL connection. """ self._check_closed() # Initially, the buffer size is the default buffer size. # Unfortunately, pending() does not return meaningful data until # recv() is called, so we only adjust the buffer size after the # first read buffer_size = self._buffer_size buffer_length = len(self._buffer) # Read only the specified amount of data while buffer_length < amt or amt is None: # if amt is None (read till the end), fills in self._buffer if amt is not None: buffer_size = min(amt - buffer_length, buffer_size) try: data = self._connection.recv(buffer_size) self._buffer = self._buffer + data buffer_length = len(self._buffer) # More bytes to read? pending = self._connection.pending() if pending == 0 and buffer_length == amt: # we're done here break except SSL.SSLError as err: if err.args[0] == SSL.SSL_ERROR_ZERO_RETURN: # Nothing more to be read break elif err.args[0] == SSL.SSL_ERROR_SYSCALL: e = sys.exc_info()[1] print("SSL exception", e.args) break elif err.args[0] == SSL.SSL_ERROR_WANT_WRITE: self._poll(select.POLLOUT, 'read') elif err.args[0] == SSL.SSL_ERROR_WANT_READ: self._poll(select.POLLIN, 'read') if amt: ret = self._buffer[:amt] self._buffer = self._buffer[amt:] else: ret = self._buffer self._buffer = bstr("") self._pos = self._pos + len(ret) return ret
def generate_random_string(length=20): if not length: return '' random_bytes = 16 length = int(length) s = hashlib.new('sha1') s.update(bstr("%.8f" % time.time())) s.update(bstr(str(os.getpid()))) devrandom = open('/dev/urandom', mode='rb') result = [] cur_length = 0 while 1: s.update(bstr(devrandom.read(random_bytes))) buf = s.hexdigest() result.append(buf) cur_length = cur_length + len(buf) if cur_length >= length: break devrandom.close() result = ''.join(result)[:length] return result.lower()
def read(self, amt=None): """ Reads up to amt bytes from the SSL connection. """ self._check_closed() # Initially, the buffer size is the default buffer size. # Unfortunately, pending() does not return meaningful data until # recv() is called, so we only adjust the buffer size after the # first read buffer_size = self._buffer_size buffer_length = len(self._buffer) # Read only the specified amount of data while buffer_length < amt or amt is None: # if amt is None (read till the end), fills in self._buffer if amt is not None: buffer_size = min(amt - buffer_length, buffer_size) try: data = self._connection.recv(buffer_size) self._buffer = self._buffer + data buffer_length = len(self._buffer) # More bytes to read? pending = self._connection.pending() if pending == 0: # we're done here break except SSL.ZeroReturnError: # Nothing more to be read break except SSL.SysCallError: e = sys.exc_info()[1] print("SSL exception", e.args) break except SSL.WantWriteError: self._poll(select.POLLOUT, 'read') except SSL.WantReadError: self._poll(select.POLLIN, 'read') if amt: ret = self._buffer[:amt] self._buffer = self._buffer[amt:] else: ret = self._buffer self._buffer = bstr("") self._pos = self._pos + len(ret) return ret
def acquire(self): """acquire the lock; else raise LockfileLockedException.""" try: fcntl.flock(self.f, fcntl.LOCK_EX|fcntl.LOCK_NB) except IOError: if sys.exc_info()[1].errno == EWOULDBLOCK: raise LockfileLockedException( "cannot acquire lock on %s." % self.lockfile, None, sys.exc_info()[2]) else: raise # unlock upon exit fcntl.fcntl(self.f, fcntl.F_SETFD, 1) # truncate and write the pid os.ftruncate(self.f, 0) os.write(self.f, bstr(str(self.pid) + '\n'))
def readline(self, length=None): """ Reads a single line (up to `length' characters long) from the SSL connection. """ self._check_closed() while True: # charcount contains the number of chars to be outputted (or None # if none to be outputted at this time) charcount = None i = self._buffer.find(bstr('\n')) if i >= 0: # Go one char past newline charcount = i + 1 elif length and len(self._buffer) >= length: charcount = length if charcount is not None: ret = self._buffer[:charcount] self._buffer = self._buffer[charcount:] self._pos = self._pos + len(ret) return ret # Determine the number of chars to be read next bufsize = self._buffer_size if length: # we know length > len(self._buffer) bufsize = min(self._buffer_size, length - len(self._buffer)) try: data = self._connection.recv(bufsize) self._buffer = self._buffer + data except SSL.SSLError as err: if err.args[0] == SSL.SSL_ERROR_ZERO_RETURN: # Nothing more to be read break elif err.args[0] == SSL.SSL_ERROR_WANT_WRITE: self._poll(select.POLLOUT, 'readline') elif err.args[0] == SSL.SSL_ERROR_WANT_READ: self._poll(select.POLLIN, 'readline') # We got here if we're done reading, so return everything ret = self._buffer self._buffer = "" self._pos = self._pos + len(ret) return ret
def acquire(self): """acquire the lock; else raise LockfileLockedException.""" try: fcntl.flock(self.f, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: if sys.exc_info()[1].errno == EWOULDBLOCK: raise LockfileLockedException( "cannot acquire lock on %s." % self.lockfile, None, sys.exc_info()[2]) else: raise # unlock upon exit fcntl.fcntl(self.f, fcntl.F_SETFD, 1) # truncate and write the pid os.ftruncate(self.f, 0) os.write(self.f, bstr(str(self.pid) + '\n'))
def run(self): log_debug(2) r = self.repository files = r.list_files() if not files: die(1, "No managed files.") label = "Config Channel" maxlen = max([len(s[0]) for s in files]) maxlen = max(maxlen, len(label)) + 2 print("%-10s %8s %-8s %10s %+3s %*s %s" % ('Mode', 'Owner', 'Group', 'Size', 'Rev', maxlen, label, "File")) arg_files = [] if len(sys.argv) > 2: arg_files = sys.argv[2:len(sys.argv)] for file in files: if len(arg_files) and not file[1] in arg_files: continue # Get the file info finfo = r.get_file_info(file[1])[1] # Get the file length if finfo['encoding'] == 'base64': fsize = len(base64.decodestring(bstr(finfo['file_contents']))) else: # * indicates raw 'unencoded' size fsize = '*' + str(len(finfo['file_contents'])) if finfo['filetype'] == 'symlink': permstr = ostr_to_sym('777', finfo['filetype']) dest = "%s -> %s" % (file[1], finfo['symlink']) fsize = str(len(finfo['symlink'])) finfo['username'] = '******' finfo['groupname'] = 'root' else: permstr = ostr_to_sym(finfo['filemode'], finfo['filetype']) or '' dest = file[1] print("%10s %8s %-8s %10s %+3s %*s %s" % (permstr, finfo['username'], finfo['groupname'], fsize, finfo['revision'], maxlen, file[0], dest))
def readline(self, length=None): """ Reads a single line (up to `length' characters long) from the SSL connection. """ self._check_closed() while True: # charcount contains the number of chars to be outputted (or None # if none to be outputted at this time) charcount = None i = self._buffer.find(bstr('\n')) if i >= 0: # Go one char past newline charcount = i + 1 elif length and len(self._buffer) >= length: charcount = length if charcount is not None: ret = self._buffer[:charcount] self._buffer = self._buffer[charcount:] self._pos = self._pos + len(ret) return ret # Determine the number of chars to be read next bufsize = self._buffer_size if length: # we know length > len(self._buffer) bufsize = min(self._buffer_size, length - len(self._buffer)) try: data = self._connection.recv(bufsize) self._buffer = self._buffer + data except SSL.ZeroReturnError: # Nothing more to be read break except SSL.WantWriteError: self._poll(select.POLLOUT, 'readline') except SSL.WantReadError: self._poll(select.POLLIN, 'readline') # We got here if we're done reading, so return everything ret = self._buffer self._buffer = "" self._pos = self._pos + len(ret) return ret
def log_debug(self, debug_level, *args): if debug_level <= self.debug_level: info_out = ( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())), self.get_caller(), " ".join([str(x) for x in args]) ) outstring = "%s %s: %s\n" % info_out sys.stdout.write( outstring ) if not Logger.logfile is None: try: fd = os.open(Logger.logfile, os.O_APPEND | os.O_RDWR | os.O_CREAT, int("0600", 8)) os.write(fd, bstr(outstring)) os.close(fd) except IOError: raise
def send_http(self, host, handler="/RPC2"): if not self.__processed: raise NotProcessed self._host = host if self._connection is None: raise Exception("No connection object found") self._connection.connect() # wrap self data into binary object, otherwise HTTPConnection.request # will encode it as ISO-8859-1 https://docs.python.org/3/library/http.client.html#httpconnection-objects self._connection.request(self.method, handler, body=bstr(self.data), headers=self.headers) response = self._connection.getresponse() if not self.response_acceptable(response): raise xmlrpclib.ProtocolError( "%s %s" % (self._host, handler), response.status, response.reason, response.msg ) # A response object has read() and close() methods, so we can safely # pass the whole object back return response.msg, response
def genServerRpm(d, verbosity=0): """ generates server's SSL key set RPM """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) server_key_name = os.path.basename(d['--server-key']) server_key = os.path.join(serverKeyPairDir, server_key_name) server_cert_name = os.path.basename(d['--server-cert']) server_cert = os.path.join(serverKeyPairDir, server_cert_name) server_cert_req_name = os.path.basename(d['--server-cert-req']) server_cert_req = os.path.join(serverKeyPairDir, server_cert_req_name) jabberd_ssl_cert_name = os.path.basename(d['--jabberd-ssl-cert']) jabberd_ssl_cert = os.path.join(serverKeyPairDir, jabberd_ssl_cert_name ) server_rpm_name = os.path.basename(d['--server-rpm']) server_rpm = os.path.join(serverKeyPairDir, server_rpm_name) postun_scriptlet = os.path.join(d['--dir'], 'postun.scriptlet') genServerRpm_dependencies(d) if verbosity>=0: sys.stderr.write("\n...working...\n") # check for old installed RPM. oldHdr = getInstalledHeader(LEGACY_SERVER_RPM_NAME1) if oldHdr and LEGACY_SERVER_RPM_NAME1 != server_rpm_name: sys.stderr.write(""" ** NOTE ** older-styled RPM installed (%s), it needs to be removed before installing the web server's RPM that is about to generated. """ % LEGACY_SERVER_RPM_NAME1) if not oldHdr: oldHdr = getInstalledHeader(LEGACY_SERVER_RPM_NAME2) if oldHdr and LEGACY_SERVER_RPM_NAME2 != server_rpm_name: sys.stderr.write(""" ** NOTE ** older-styled RPM installed (%s), it needs to be removed before installing the web server's RPM that is about to generated. """ % LEGACY_SERVER_RPM_NAME2) # check for new installed RPM. # Work out the release number. hdr = getInstalledHeader(server_rpm_name) #find RPMs in the directory as well. filenames = glob.glob("%s-*.noarch.rpm" % server_rpm) if filenames: filename = sortRPMs(filenames)[-1] h = get_package_header(filename) if hdr is None: hdr = h else: comp = hdrLabelCompare(h, hdr) if comp > 0: hdr = h epo, ver, rel = None, '1.0', '0' if hdr is not None: epo, ver, rel = hdr['epoch'], hdr['version'], hdr['release'] # bump the release - and let's not be too smart about it # assume the release is a number. if rel: rel = str(int(rel)+1) description = SERVER_RPM_SUMMARY + """ Best practices suggests that this RPM should only be installed on the web server with this hostname: %s """ % d['--set-hostname'] # Determine which jabberd user exists: jabberd_user = None possible_jabberd_users = ['jabberd', 'jabber'] for juser_attempt in possible_jabberd_users: try: pwd.getpwnam(juser_attempt) jabberd_user = juser_attempt except: # user doesn't exist, try the next pass if jabberd_user is None: print("WARNING: No jabber/jabberd user on system, skipping " + "jabberd.pem generation.") jabberd_cert_string = "" if jabberd_user is not None: jabberd_cert_string = \ "/etc/pki/spacewalk/jabberd/server.pem:0600,%s,%s=%s" % \ (jabberd_user, jabberd_user, repr(cleanupAbsPath(jabberd_ssl_cert))) ## build the server RPM args = (os.path.join(CERT_PATH, 'gen-rpm.sh') + " " "--name %s --version %s --release %s --packager %s --vendor %s " "--group 'RHN/Security' --summary %s --description %s --postun %s " "/etc/httpd/conf/ssl.key/server.key:0600=%s " "/etc/httpd/conf/ssl.csr/server.csr=%s " "/etc/httpd/conf/ssl.crt/server.crt=%s " "%s" % (repr(server_rpm_name), ver, rel, repr(d['--rpm-packager']), repr(d['--rpm-vendor']), repr(SERVER_RPM_SUMMARY), repr(description), repr(cleanupAbsPath(postun_scriptlet)), repr(cleanupAbsPath(server_key)), repr(cleanupAbsPath(server_cert_req)), repr(cleanupAbsPath(server_cert)), jabberd_cert_string )) serverRpmName = "%s-%s-%s" % (server_rpm, ver, rel) if verbosity >= 0: print(""" Generating web server's SSL key pair/set RPM: %s.src.rpm %s.noarch.rpm""" % (serverRpmName, serverRpmName)) if verbosity > 1: print("Commandline:", args) if verbosity >= 4: print('Current working directory:', os.getcwd()) print("Writing postun_scriptlet:", postun_scriptlet) open(postun_scriptlet, 'w').write(POST_UNINSTALL_SCRIPT) _disableRpmMacros() cwd = chdir(serverKeyPairDir) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) _reenableRpmMacros() os.unlink(postun_scriptlet) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret or not os.path.exists("%s.noarch.rpm" % serverRpmName): raise GenServerRpmException("web server's SSL key set RPM generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) os.chmod('%s.noarch.rpm' % serverRpmName, int('0600',8)) # generic the tarball necessary for Spacewalk Proxy against hosted installations tarballFilepath = genProxyServerTarball(d, version=ver, release=rel, verbosity=verbosity) # write-out latest.txt information latest_txt = os.path.join(serverKeyPairDir, 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s.noarch.rpm\n' % os.path.basename(serverRpmName))) fo.write(bstr('%s.src.rpm\n' % os.path.basename(serverRpmName))) fo.write(bstr('%s\n' % os.path.basename(tarballFilepath))) fo.close() os.chmod(latest_txt, int('0600',8)) if verbosity >= 0: print(""" Deploy the server's SSL key pair/set RPM: (NOTE: the Red Hat Satellite or Proxy installers may do this step for you.) The "noarch" RPM needs to be deployed to the machine working as a web server, or Red Hat Satellite, or Spacewalk Proxy. Presumably %s.""" % repr(d['--set-hostname'])) return "%s.noarch.rpm" % serverRpmName
def process(self, file_struct, directory=None, strict_ownership=1): # Older servers will not return directories; if filetype is missing, # assume file if file_struct.get('filetype') == 'directory': if directory is None: directory = "" return None, utils.mkdir_p(directory + file_struct['path']) if directory: directory += os.path.split(file_struct['path'])[0] if file_struct.get('filetype') == 'symlink': if 'symlink' not in file_struct: raise Exception("Missing key symlink") (fullpath, dirs_created, fh) = maketemp(prefix=".rhn-cfg-tmp", directory=directory, symlink=file_struct['symlink']) return fullpath, dirs_created for k in self.file_struct_fields.keys(): if k not in file_struct: # XXX raise Exception("Missing key %s" % k) encoding = '' if 'encoding' in file_struct: encoding = file_struct['encoding'] contents = file_struct['file_contents'] if contents and (encoding == 'base64'): contents = base64.decodestring(bstr(contents)) delim_start = file_struct['delim_start'] delim_end = file_struct['delim_end'] if ('checksum' in file_struct and 'checksum_type' in file_struct and 'verify_contents' in file_struct and file_struct['verify_contents']): if file_struct['checksum'] != utils.getContentChecksum( file_struct['checksum_type'], contents): raise Exception( "Corrupt file received: Content checksums do not match!") elif ('md5sum' in file_struct and 'verify_contents' in file_struct and file_struct['verify_contents']): if file_struct['md5sum'] != utils.getContentChecksum( 'md5', contents): raise Exception( "Corrupt file received: Content checksums do not match!") elif ('verify_contents' in file_struct and file_struct['verify_contents']): raise Exception( "Corrupt file received: missing checksum information!") fh = None (fullpath, dirs_created, fh) = maketemp(prefix=".rhn-cfg-tmp", directory=directory) try: fh.write(sstr(contents)) except Exception: if fh: fh.close() # don't leak fds... raise else: fh.close() # try to set mtime and ctime of the file to # the last modified time on the server if 'modified' in file_struct: try: modified = xmlrpc_time(file_struct['modified'].value) epoch_time = time.mktime(modified) os.utime(fullpath, (epoch_time, epoch_time)) except (ValueError, AttributeError): # we can't parse modified time pass return fullpath, dirs_created
def diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if 'encoding' in info and info['file_contents']: if info['encoding'] == 'base64': info['file_contents'] = base64.decodestring( bstr(info['file_contents'])) else: die(9, 'Error: unknown encoding %s' % info['encoding']) except cfg_exceptions.RepositoryFileMissingError: die( 2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink': die( 8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file): die( 8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % ( path, src_link, path, dest_link) return "" fromlines = sstr(info['file_contents']).splitlines(1) tolines = open(local_file, 'r').readlines() diff_output = difflib.unified_diff(fromlines, tolines, info['path'], local_file) first_row = second_row = '' try: first_row = next(diff_output) second_row = next(diff_output) except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not 'selinux_ctx' in local_info: local_info['selinux_ctx'] = '' if 'selinux_ctx' not in info: info['selinux_ctx'] = '' if not first_row and not self.__attributes_differ(info, local_info): return "" else: template = "--- %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if 'modified' not in info: info['modified'] = '' first_row = template % ( path, str(info['modified']), ostr_to_sym(info['filemode'], info['filetype']), info['username'], info['groupname'], info['selinux_ctx'], channel, info['revision'], ) second_row = template % ( local_file, f_date(datetime.fromtimestamp( local_info['mtime'])), ostr_to_sym(local_info['mode'], 'file'), local_info['user'], local_info['group'], local_info['selinux_ctx'], 'local file', None) return first_row + '\n' + second_row + '\n' + ''.join( list(diff_output))
def main(self): if self.options.serverUrl: rhnreg.cfg.set("serverURL", self.options.serverUrl) if self.options.sslCACert: rhnreg.cfg.set("sslCACert", self.options.sslCACert) if not (self.options.activationkey or (self.options.username and self.options.password)): print(_("A username and password are required "\ "to register a system.")) sys.exit(-1) if rhnreg.registered() and not self.options.force: print(_("This system is already registered. Use --force to override")) sys.exit(-1) rhnreg.getCaps() if not self.options.nopackages: getArch = 0 if rhnreg.cfg['supportsExtendedPackageProfile']: getArch = 1 packageList = pkgUtils.getInstalledPackageList(getArch=getArch) else: packageList = [] hardwareList = hardware.Hardware() if self.options.profilename: profilename = self.options.profilename else: profilename = RegisterKsCli.__generateProfileName(hardwareList) other = {} if self.options.systemorgid: other['org_id'] = self.options.systemorgid # Try to get the virt uuid and put it in "other". (virt_uuid, virt_type) = rhnreg.get_virt_info() if not virt_uuid is None: other['virt_uuid'] = virt_uuid other['virt_type'] = virt_type # If specified, send up the EUS channel label for subscription. if self.options.use_eus_channel: if self.options.activationkey: print(_("Usage of --use-eus-channel option with --activationkey is not supported. Please use username and password instead.")) sys.exit(-1) if not rhnreg.server_supports_eus(): print(_("The server you are registering against does not support EUS.")) sys.exit(-1) channels = rhnreg.getAvailableChannels(self.options.username, self.options.password) other['channel'] = channels['default_channel'] try: systemId = rhnreg.registerSystem(self.options.username, self.options.password, profilename, self.options.activationkey, other) except (up2dateErrors.AuthenticationTicketError, up2dateErrors.RhnUuidUniquenessError, up2dateErrors.CommunicationError, up2dateErrors.AuthenticationOrAccountCreationError): e = sys.exc_info()[1] print("%s" % e.errmsg) sys.exit(1) # collect hardware info, inluding hostname if not self.options.nohardware: rhnreg.sendHardware(systemId, hardwareList) if not self.options.nopackages: rhnreg.sendPackages(systemId, packageList) if self.options.contactinfo: print(_("Warning: --contactinfo option has been deprecated. Please login to the server web user Interface and update your contactinfo. ")) # write out the new id rhnreg.writeSystemId(bstr(systemId)) # assume successful communication with server # remember to save the config options rhnreg.cfg.save() # Send virtualization information to the server. We must do this # *after* writing out the system id. if not self.options.novirtinfo: rhnreg.sendVirtInfo(systemId) # do this after writing out system id, bug #147513 if not self.options.norhnsd: rhnreg.startRhnsd() try: present, conf_changed = rhnreg.pluginEnable() if not present: sys.stderr.write(sstr(_("Warning: %s is not present, could not enable it.") % PM_PLUGIN_NAME)) except IOError: e = sys.exc_info()[1] sys.stderr.write(sstr(_("Warning: Could not open %s\n%s is not enabled.\n") % (PM_PLUGIN_CONF, PM_PLUGIN_NAME) + e.errmsg)) RegisterKsCli.__runRhnCheck(self.options.verbose)
def process(self, file_struct, directory=None, strict_ownership=1): # Older servers will not return directories; if filetype is missing, # assume file if file_struct.get('filetype') == 'directory': if directory is None: directory = "" return None, utils.mkdir_p(directory + file_struct['path']) if directory: directory += os.path.split(file_struct['path'])[0] if file_struct.get('filetype') == 'symlink': if 'symlink' not in file_struct: raise Exception("Missing key symlink") (fullpath, dirs_created, fd) = maketemp(prefix=".rhn-cfg-tmp", directory=directory) os.close(fd) os.unlink(fullpath) os.symlink(file_struct['symlink'], fullpath) return fullpath, dirs_created for k in self.file_struct_fields.keys(): if k not in file_struct: # XXX raise Exception("Missing key %s" % k) encoding = '' if 'encoding' in file_struct: encoding = file_struct['encoding'] contents = file_struct['file_contents'] if contents and (encoding == 'base64'): contents = base64.decodestring(bstr(contents)) delim_start = file_struct['delim_start'] delim_end = file_struct['delim_end'] if ('checksum' in file_struct and 'checksum_type' in file_struct and 'verify_contents' in file_struct and file_struct['verify_contents']): if file_struct['checksum'] != utils.getContentChecksum( file_struct['checksum_type'], contents): raise Exception("Corrupt file received: Content checksums do not match!") elif ('md5sum' in file_struct and 'verify_contents' in file_struct and file_struct['verify_contents']): if file_struct['md5sum'] != utils.getContentChecksum( 'md5', contents): raise Exception("Corrupt file received: Content checksums do not match!") elif ('verify_contents' in file_struct and file_struct['verify_contents']): raise Exception("Corrupt file received: missing checksum information!") (fullpath, dirs_created, fd) = maketemp(prefix=".rhn-cfg-tmp", directory=directory) try: os.write(fd, bstr(contents)) except Exception: raise finally: os.close(fd) # try to set mtime and ctime of the file to # the last modified time on the server if 'modified' in file_struct: try: modified = xmlrpc_time(file_struct['modified'].value) epoch_time = time.mktime(modified) os.utime(fullpath, (epoch_time, epoch_time)) except (ValueError, AttributeError): # we can't parse modified time pass return fullpath, dirs_created
def diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if 'encoding' in info and info['file_contents']: if info['encoding'] == 'base64': info['file_contents'] = base64.decodestring(bstr(info['file_contents'])) else: die(9, 'Error: unknown encoding %s' % info['encoding']) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink' : die(8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file) : die(8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % (path,src_link, path, dest_link) return "" response_output = "" content_differs = False if 'is_binary' in info and info['is_binary'] == 'Y': from_content = info['file_contents'] to_file = open(local_file, 'rb') to_content = to_file.read() to_file.close() if len(from_content) != len(to_content): content_differs = True else: for i in range(len(from_content)): if from_content[i] != to_content[i]: content_differs = True break if content_differs: response_output = "Binary file content differs\n" else: fromlines = sstr(info['file_contents']).splitlines(1) tofile = open(local_file, 'r') tolines = tofile.readlines() tofile.close() diff_output = difflib.unified_diff(fromlines, tolines, info['path'], local_file) first_row = second_row = '' try: first_row = next(diff_output) # if content was same, exception thrown so following # lines don't execute content_differs = True second_row = next(diff_output) response_output = ''.join(list(diff_output)) except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not 'selinux_ctx' in local_info: local_info['selinux_ctx'] = '' if 'selinux_ctx' not in info: info['selinux_ctx'] = '' if not content_differs and not self.__attributes_differ(info, local_info): return "" else: template = "%s %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if 'modified' not in info: info['modified'] = '' first_row = template % ('---', path, str(info['modified']), ostr_to_sym(info['filemode'], info['filetype']), info['username'], info['groupname'], info['selinux_ctx'], channel, info['revision'], ) second_row = template % ('+++', local_file, f_date(datetime.fromtimestamp(local_info['mtime'])), ostr_to_sym(local_info['mode'], 'file'), local_info['user'], local_info['group'], local_info['selinux_ctx'], 'local file', None ) return first_row + '\n' + second_row + '\n' + response_output
def report(problem_dir): problem_dir = os.path.normpath(os.path.abspath(problem_dir)) basename = os.path.basename(problem_dir) log = up2dateLog.initLog() if not (os.path.exists(problem_dir) and os.path.isdir(problem_dir)): log.log_me("The specified path [%s] is not a valid directory." % problem_dir) return -1 crash_items = ['analyzer', 'cmdline', 'reason'] if os.path.exists(os.path.join(problem_dir, 'vmcore')): crash_items = ['analyzer', 'vmcore-dmesg.txt'] for item in crash_items: item_path = os.path.join(problem_dir, item) if not os.path.exists(item_path): log.log_me("Crash directory [%s] is incomplete or invalid" % problem_dir) return -1 server = rhnserver.RhnServer() if not server.capabilities.hasCapability('abrt'): return -1 systemid = up2dateAuth.getSystemId() # Package information pkg_data = {} for item in ['package', 'pkg_name', 'pkg_epoch', 'pkg_version', 'pkg_release', 'pkg_arch']: pkg_item_path = os.path.join(problem_dir, item) if os.path.exists(pkg_item_path): filecontent = _readline(pkg_item_path) if filecontent: pkg_data[item] = filecontent # Crash information crash_data = {'crash': basename, 'path': problem_dir} # Crash count crash_count = _readline(os.path.join(problem_dir, 'count')) if crash_count: crash_data['count'] = crash_count # Create record about the crash r = server.abrt.create_crash(systemid, crash_data, pkg_data) if (r < 0): # Error creating new crash report log.log_me("Error creating new crash report.") return -1 # Upload every particular file in the problem directory to the server for i in os.listdir(problem_dir): path = os.path.join(problem_dir, i) if not os.path.isfile(path): continue filesize = os.stat(path).st_size crash_file_data = {'filename': os.path.basename(i), 'path': path, 'filesize': filesize, 'filecontent': base64.encodestring(bstr("")), 'content-encoding': 'base64'} if server.abrt.is_crashfile_upload_enabled(systemid) and filesize <= server.abrt.get_crashfile_uploadlimit(systemid): f = open(path, 'r') try: crash_file_data['filecontent'] = base64.encodestring(f.read()) finally: f.close() server.abrt.upload_crash_file(systemid, basename, crash_file_data) return 1
def genPublicCaCert(password, d, verbosity=0, forceYN=0): """ public CA certificate (client-side) generation """ ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) genPublicCaCert_dependencies(password, d, forceYN) configFile = ConfigFile(ca_openssl_cnf) if '--set-hostname' in d: del d['--set-hostname'] configFile.save(d, caYN=1, verbosity=verbosity) args = ("/usr/bin/openssl req -passin pass:%s -text -config %s " "-new -x509 -days %s -%s -key %s -out %s" % ('%s', repr(cleanupAbsPath(configFile.filename)), repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(ca_key)), repr(cleanupAbsPath(ca_cert)))) if verbosity >= 0: print("\nGenerating public CA certificate: %s" % ca_cert) print("Using distinguishing variables:") for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-common-name', '--set-email'): print(' %s%s = "%s"' % (k, ' '*(18-len(k)), d[k])) if verbosity > 1: print("Commandline:", args % "PASSWORD") try: rotated = rotateFile(filepath=ca_cert, verbosity=verbosity) if verbosity>=0 and rotated: print("Rotated: %s --> %s" \ % (d['--ca-cert'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPublicCaCertException("Certificate Authority public " "SSL certificate generation failed:\n%s\n" "%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s\n' % ca_cert_name)) fo.close() # permissions: os.chmod(ca_cert, int('0644',8)) os.chmod(latest_txt, int('0644',8))
def genCaRpm(d, verbosity=0): """ generates ssl cert RPM. """ ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) ca_cert_rpm_name = os.path.basename(d['--ca-cert-rpm']) ca_cert_rpm = os.path.join(d['--dir'], ca_cert_rpm_name) genCaRpm_dependencies(d) if verbosity>=0: sys.stderr.write("\n...working...") # Work out the release number. hdr = getInstalledHeader(ca_cert_rpm) #find RPMs in the directory filenames = glob.glob("%s-*.noarch.rpm" % ca_cert_rpm) if filenames: filename = sortRPMs(filenames)[-1] h = get_package_header(filename) if hdr is None: hdr = h else: comp = hdrLabelCompare(h, hdr) if comp > 0: hdr = h epo, ver, rel = None, '1.0', '0' if hdr is not None: epo, ver, rel = hdr['epoch'], hdr['version'], hdr['release'] # bump the release - and let's not be too smart about it # assume the release is a number. if rel: rel = str(int(rel)+1) update_trust_script = os.path.join(CERT_PATH, 'update-ca-cert-trust.sh') # build the CA certificate RPM args = (os.path.join(CERT_PATH, 'gen-rpm.sh') + " " "--name %s --version %s --release %s --packager %s --vendor %s " "--group 'RHN/Security' --summary %s --description %s " "--post %s --postun %s " "/usr/share/rhn/%s=%s" % (repr(ca_cert_rpm_name), ver, rel, repr(d['--rpm-packager']), repr(d['--rpm-vendor']), repr(CA_CERT_RPM_SUMMARY), repr(CA_CERT_RPM_SUMMARY), repr(update_trust_script), repr(update_trust_script), repr(ca_cert_name), repr(cleanupAbsPath(ca_cert)))) clientRpmName = '%s-%s-%s' % (ca_cert_rpm, ver, rel) if verbosity >= 0: print(""" Generating CA public certificate RPM: %s.src.rpm %s.noarch.rpm""" % (clientRpmName, clientRpmName)) if verbosity > 1: print("Commandline:", args) _disableRpmMacros() cwd = chdir(d['--dir']) try: ret, out_stream, err_stream = rhn_popen(args) except Exception: chdir(cwd) _reenableRpmMacros() raise chdir(cwd) _reenableRpmMacros() out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret or not os.path.exists("%s.noarch.rpm" % clientRpmName): raise GenCaCertRpmException("CA public SSL certificate RPM generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) os.chmod('%s.noarch.rpm' % clientRpmName, int('0644',8)) # write-out latest.txt information latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s\n' % ca_cert_name)) fo.write(bstr('%s.noarch.rpm\n' % os.path.basename(clientRpmName))) fo.write(bstr('%s.src.rpm\n' % os.path.basename(clientRpmName))) fo.close() os.chmod(latest_txt, int('0644',8)) if verbosity >= 0: print(""" Make the public CA certficate publically available: (NOTE: the Red Hat Satellite or Proxy installers may do this step for you.) The "noarch" RPM and raw CA certificate can be made publically accessible by copying it to the /var/www/html/pub directory of your Red Hat Satellite or Proxy server.""") return '%s.noarch.rpm' % clientRpmName
def writeError(e): sys.stderr.write(bstr('\nERROR: %s\n' % e))