def generate_winrm_x509_cert(user_id, project_id, bits=2048): """Generate a cert for passwordless auth for user in project.""" subject = '/CN=%s-%s' % (project_id, user_id) upn = '%s@localhost' % user_id with utils.tempdir() as tmpdir: keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf')) _create_x509_openssl_config(conffile, upn) (certificate, _err) = utils.execute( 'openssl', 'req', '-x509', '-nodes', '-days', '3650', '-config', conffile, '-newkey', 'rsa:%s' % bits, '-outform', 'PEM', '-keyout', keyfile, '-subj', subject, '-extensions', 'v3_req_client') (out, _err) = utils.execute('openssl', 'pkcs12', '-export', '-inkey', keyfile, '-password', 'pass:'******'base64') fingerprint = generate_x509_fingerprint(certificate) return (private_key, certificate, fingerprint)
def _make_base_file(self, checksum=True, lock=True): """Make a base file for testing.""" with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname = os.path.join(tmpdir, 'aaa') base_file = open(fname, 'w') base_file.write('data') base_file.close() if lock: lockdir = os.path.join(tmpdir, 'locks') lockname = os.path.join(lockdir, 'patron-aaa') os.mkdir(lockdir) lock_file = open(lockname, 'w') lock_file.write('data') lock_file.close() base_file = open(fname, 'r') if checksum: imagecache.write_stored_checksum(fname) base_file.close() yield fname
def test_verify_checksum_invalid_repaired(self): with utils.tempdir() as tmpdir: image_cache_manager, fname = ( self._check_body(tmpdir, "csum invalid, not json")) res = image_cache_manager._verify_checksum( self.img, fname, create_if_missing=True) self.assertIsNone(res)
def _sign_csr(csr_text, ca_folder): with utils.tempdir() as tmpdir: inbound = os.path.join(tmpdir, 'inbound.csr') outbound = os.path.join(tmpdir, 'outbound.csr') try: with open(inbound, 'w') as csrfile: csrfile.write(csr_text) except IOError: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Failed to write inbound.csr')) LOG.debug('Flags path: %s', ca_folder) start = os.getcwd() # Change working dir to CA fileutils.ensure_tree(ca_folder) os.chdir(ca_folder) utils.execute('openssl', 'ca', '-batch', '-out', outbound, '-config', './openssl.cnf', '-infiles', inbound) out, _err = utils.execute('openssl', 'x509', '-in', outbound, '-serial', '-noout') serial = string.strip(out.rpartition('=')[2]) os.chdir(start) with open(outbound, 'r') as crtfile: return (serial, crtfile.read())
def get_encoded_zip(self, project_id): # Make a payload.zip with utils.tempdir() as tmpdir: filename = "payload.zip" zippath = os.path.join(tmpdir, filename) z = zipfile.ZipFile(zippath, "w", zipfile.ZIP_DEFLATED) boot_script = _load_boot_script() # genvpn, sign csr crypto.generate_vpn_files(project_id) z.writestr('autorun.sh', boot_script) crl = os.path.join(crypto.ca_folder(project_id), 'crl.pem') z.write(crl, 'crl.pem') server_key = os.path.join(crypto.ca_folder(project_id), 'server.key') z.write(server_key, 'server.key') ca_crt = os.path.join(crypto.ca_path(project_id)) z.write(ca_crt, 'ca.crt') server_crt = os.path.join(crypto.ca_folder(project_id), 'server.crt') z.write(server_crt, 'server.crt') z.close() zippy = open(zippath, "r") # NOTE(vish): run instances expects encoded userdata, it is decoded # in the get_metadata_call. autorun.sh also decodes the zip file, # hence the double encoding. encoded = zippy.read().encode("base64").encode("base64") zippy.close() return encoded
def _make_vfat(self, path, tmpdir): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. with open(path, 'wb') as f: f.truncate(CONFIGDRIVESIZE_BYTES) utils.mkfs('vfat', path, label='config-2') with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd( 'mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), path, mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation='mount', error=err) mounted = True # NOTE(mikal): I can't just use shutils.copytree here, # because the destination directory already # exists. This is annoying. for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True)
def _make_vfat(self, path, tmpdir): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. with open(path, 'wb') as f: f.truncate(CONFIGDRIVESIZE_BYTES) utils.mkfs('vfat', path, label='config-2') with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd('mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), path, mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation='mount', error=err) mounted = True # NOTE(mikal): I can't just use shutils.copytree here, # because the destination directory already # exists. This is annoying. for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True)
def generate_winrm_x509_cert(user_id, project_id, bits=2048): """Generate a cert for passwordless auth for user in project.""" subject = '/CN=%s-%s' % (project_id, user_id) upn = '%s@localhost' % user_id with utils.tempdir() as tmpdir: keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf')) _create_x509_openssl_config(conffile, upn) (certificate, _err) = utils.execute('openssl', 'req', '-x509', '-nodes', '-days', '3650', '-config', conffile, '-newkey', 'rsa:%s' % bits, '-outform', 'PEM', '-keyout', keyfile, '-subj', subject, '-extensions', 'v3_req_client') (out, _err) = utils.execute('openssl', 'pkcs12', '-export', '-inkey', keyfile, '-password', 'pass:'******'base64') fingerprint = generate_x509_fingerprint(certificate) return (private_key, certificate, fingerprint)
def test_ensure_ca_filesystem_chdir(self, *args, **kargs): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) start = os.getcwd() self.assertRaises(processutils.ProcessExecutionError, crypto.ensure_ca_filesystem) self.assertEqual(start, os.getcwd())
def test_launch_vpn_instance(self): self.stubs.Set(self.cloudpipe.compute_api, "create", lambda *a, **kw: (None, "r-fakeres")) with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir, keys_path=tmpdir) crypto.ensure_ca_filesystem() self.cloudpipe.launch_vpn_instance(self.context)
def test_get_encoded_zip(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) crypto.ensure_ca_filesystem() ret = self.cloudpipe.get_encoded_zip(self.project) self.assertTrue(ret)
def test_compute_manager(self): was = {'called': False} def fake_get_all_by_filters(context, *args, **kwargs): was['called'] = True instances = [] for x in xrange(2): instances.append(fake_instance.fake_db_instance( image_ref='1', uuid=x, name=x, vm_state='', task_state='')) return instances with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.stubs.Set(db, 'instance_get_all_by_filters', fake_get_all_by_filters) compute = importutils.import_object(CONF.compute_manager) self.flags(use_local=True, group='conductor') compute.conductor_api = conductor.API() compute._run_image_cache_manager_pass(None) self.assertTrue(was['called'])
def test_compute_manager(self): was = {'called': False} def fake_get_all_by_filters(context, *args, **kwargs): was['called'] = True instances = [] for x in xrange(2): instances.append( fake_instance.fake_db_instance(image_ref='1', uuid=x, name=x, vm_state='', task_state='')) return instances with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.stubs.Set(db, 'instance_get_all_by_filters', fake_get_all_by_filters) compute = importutils.import_object(CONF.compute_manager) self.flags(use_local=True, group='conductor') compute.conductor_api = conductor.API() compute._run_image_cache_manager_pass(None) self.assertTrue(was['called'])
def test_fetch_crl_file_not_found(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) self.flags(use_project_ca=True) self.assertRaises(exception.CryptoCRLFileNotFound, crypto.fetch_crl, project_id='fake')
def test_verify_checksum_invalid_repaired(self): with utils.tempdir() as tmpdir: image_cache_manager, fname = (self._check_body( tmpdir, "csum invalid, not json")) res = image_cache_manager._verify_checksum(self.img, fname, create_if_missing=True) self.assertIsNone(res)
def test_verify_checksum_invalid(self): with intercept_log_messages() as stream: with utils.tempdir() as tmpdir: image_cache_manager, fname = (self._check_body( tmpdir, "csum invalid, valid json")) res = image_cache_manager._verify_checksum(self.img, fname) self.assertFalse(res) log = stream.getvalue() self.assertNotEqual(log.find('image verification failed'), -1)
def test_verify_checksum_invalid(self): with intercept_log_messages() as stream: with utils.tempdir() as tmpdir: image_cache_manager, fname = ( self._check_body(tmpdir, "csum invalid, valid json")) res = image_cache_manager._verify_checksum(self.img, fname) self.assertFalse(res) log = stream.getvalue() self.assertNotEqual(log.find('image verification failed'), -1)
def basic_config_check(self): """Perform basic config checks before starting processing.""" # Make sure the tempdir exists and is writable try: with utils.tempdir(): pass except Exception as e: LOG.error(_LE('Temporary directory is invalid: %s'), e) sys.exit(1)
def basic_config_check(self): """Perform basic config checks before starting processing.""" # Make sure the tempdir exists and is writable try: with utils.tempdir(): pass except Exception as e: LOG.error(_LE("Temporary directory is invalid: %s"), e) sys.exit(1)
def generate_fingerprint(public_key): with utils.tempdir() as tmpdir: try: pubfile = os.path.join(tmpdir, 'temp.pub') with open(pubfile, 'w') as f: f.write(public_key) return _generate_fingerprint(pubfile) except processutils.ProcessExecutionError: raise exception.InvalidKeypair( reason=_('failed to generate fingerprint'))
def _ssh_decrypt_text(self, ssh_private_key, text): with utils.tempdir() as tmpdir: sshkey = os.path.abspath(os.path.join(tmpdir, "ssh.key")) with open(sshkey, "w") as f: f.write(ssh_private_key) try: dec, _err = utils.execute("openssl", "rsautl", "-decrypt", "-inkey", sshkey, process_input=text) return dec except processutils.ProcessExecutionError as exc: raise exception.DecryptionFailure(reason=exc.stderr)
def test_remove_base_file_dne(self): # This test is solely to execute the "does not exist" code path. We # don't expect the method being tested to do anything in this case. with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname = os.path.join(tmpdir, 'aaa') image_cache_manager = imagecache.ImageCacheManager() image_cache_manager._remove_base_file(fname)
def test_setup_key_pair(self): key_name = "%s%s" % (self.project, CONF.vpn_key_suffix) with utils.tempdir() as tmpdir: self.flags(keys_path=tmpdir) # First attempt, key does not exist (thus it is generated) res1_key = self.cloudpipe.setup_key_pair(self.context) self.assertEqual(res1_key, key_name) # Second attempt, it exists in the DB res2_key = self.cloudpipe.setup_key_pair(self.context) self.assertEqual(res2_key, res1_key)
def test_verify_checksum_invalid_json(self): with intercept_log_messages() as stream: with utils.tempdir() as tmpdir: image_cache_manager, fname = ( self._check_body(tmpdir, "csum invalid, not json")) res = image_cache_manager._verify_checksum( self.img, fname, create_if_missing=False) self.assertFalse(res) log = stream.getvalue() # NOTE(mikal): this is a skip not a fail because the file is # present, but is not in valid json format and therefore is # skipped. self.assertNotEqual(log.find('image verification skipped'), -1)
def test_verify_checksum_invalid_json(self): with intercept_log_messages() as stream: with utils.tempdir() as tmpdir: image_cache_manager, fname = (self._check_body( tmpdir, "csum invalid, not json")) res = image_cache_manager._verify_checksum( self.img, fname, create_if_missing=False) self.assertFalse(res) log = stream.getvalue() # NOTE(mikal): this is a skip not a fail because the file is # present, but is not in valid json format and therefore is # skipped. self.assertNotEqual(log.find('image verification skipped'), -1)
def test_verify_checksum_file_missing(self): with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname, info_fname, testdata = self._make_checksum(tmpdir) image_cache_manager = imagecache.ImageCacheManager() res = image_cache_manager._verify_checksum('aaa', fname) self.assertIsNone(res) # Checksum requests for a file with no checksum now have the # side effect of creating the checksum self.assertTrue(os.path.exists(info_fname))
def test_encrypt_decrypt_x509(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) project_id = "fake" crypto.ensure_ca_filesystem() cert = crypto.fetch_ca(project_id) public_key = os.path.join(tmpdir, "public.pem") with open(public_key, "w") as keyfile: keyfile.write(cert) text = "some @#!%^* test text" enc, _err = utils.execute( "openssl", "rsautl", "-certin", "-encrypt", "-inkey", "%s" % public_key, process_input=text ) dec = crypto.decrypt_text(project_id, enc) self.assertEqual(text, dec)
def _ssh_decrypt_text(self, ssh_private_key, text): with utils.tempdir() as tmpdir: sshkey = os.path.abspath(os.path.join(tmpdir, 'ssh.key')) with open(sshkey, 'w') as f: f.write(ssh_private_key) try: dec, _err = utils.execute('openssl', 'rsautl', '-decrypt', '-inkey', sshkey, process_input=text) return dec except processutils.ProcessExecutionError as exc: raise exception.DecryptionFailure(reason=exc.stderr)
def make_drive(self, path): """Make the config drive. :param path: the path to place the config drive image at :raises ProcessExecuteError if a helper process has failed. """ with utils.tempdir() as tmpdir: self._write_md_files(tmpdir) if CONF.config_drive_format == 'iso9660': self._make_iso9660(path, tmpdir) elif CONF.config_drive_format == 'vfat': self._make_vfat(path, tmpdir) else: raise exception.ConfigDriveUnknownFormat( format=CONF.config_drive_format)
def test_read_stored_checksum(self): with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') csum_input = '{"sha1": "fdghkfhkgjjksfdgjksjkghsdf"}\n' fname = os.path.join(tmpdir, 'aaa') info_fname = imagecache.get_info_filename(fname) f = open(info_fname, 'w') f.write(csum_input) f.close() csum_output = imagecache.read_stored_checksum(fname, timestamped=False) self.assertEqual(csum_input.rstrip(), '{"sha1": "%s"}' % csum_output)
def test_can_generate_x509(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) crypto.ensure_ca_filesystem() _key, cert_str = crypto.generate_x509_cert("fake", "fake") project_cert = crypto.fetch_ca(project_id="fake") signed_cert_file = os.path.join(tmpdir, "signed") with open(signed_cert_file, "w") as keyfile: keyfile.write(cert_str) project_cert_file = os.path.join(tmpdir, "project") with open(project_cert_file, "w") as keyfile: keyfile.write(project_cert) enc, err = utils.execute("openssl", "verify", "-CAfile", project_cert_file, "-verbose", signed_cert_file) self.assertFalse(err)
def test_handle_base_image_used_missing(self): img = '123' with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname = os.path.join(tmpdir, 'aaa') image_cache_manager = imagecache.ImageCacheManager() image_cache_manager.unexplained_images = [fname] image_cache_manager.used_images = {'123': (1, 0, ['banana-42'])} image_cache_manager._handle_base_image(img, fname) self.assertEqual(image_cache_manager.unexplained_images, []) self.assertEqual(image_cache_manager.removable_base_files, []) self.assertEqual(image_cache_manager.corrupt_base_files, [])
def test_read_stored_checksum_legacy_essex(self): with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname = os.path.join(tmpdir, 'aaa') old_fname = fname + '.sha1' f = open(old_fname, 'w') f.write('fdghkfhkgjjksfdgjksjkghsdf') f.close() csum_output = imagecache.read_stored_checksum(fname, timestamped=False) self.assertEqual(csum_output, 'fdghkfhkgjjksfdgjksjkghsdf') self.assertFalse(os.path.exists(old_fname)) info_fname = imagecache.get_info_filename(fname) self.assertTrue(os.path.exists(info_fname))
def test_encrypt_decrypt_x509(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) project_id = "fake" crypto.ensure_ca_filesystem() cert = crypto.fetch_ca(project_id) public_key = os.path.join(tmpdir, "public.pem") with open(public_key, 'w') as keyfile: keyfile.write(cert) text = "some @#!%^* test text" enc, _err = utils.execute('openssl', 'rsautl', '-certin', '-encrypt', '-inkey', '%s' % public_key, process_input=text) dec = crypto.decrypt_text(project_id, enc) self.assertEqual(text, dec)
def ssh_encrypt_text(ssh_public_key, text): """Encrypt text with an ssh public key. """ with utils.tempdir() as tmpdir: sslkey = os.path.abspath(os.path.join(tmpdir, 'ssl.key')) try: out = convert_from_sshrsa_to_pkcs8(ssh_public_key) with open(sslkey, 'w') as f: f.write(out) enc, _err = utils.execute('openssl', 'rsautl', '-encrypt', '-pubin', '-inkey', sslkey, '-keyform', 'PEM', process_input=text) return enc except processutils.ProcessExecutionError as exc: raise exception.EncryptionFailure(reason=exc.stderr)
def test_remove_base_file_oserror(self): with intercept_log_messages() as stream: with utils.tempdir() as tmpdir: self.flags(instances_path=tmpdir) self.flags(image_info_filename_pattern=('$instances_path/' '%(image)s.info'), group='libvirt') fname = os.path.join(tmpdir, 'aaa') os.mkdir(fname) os.utime(fname, (-1, time.time() - 3601)) # This will raise an OSError because of file permissions image_cache_manager = imagecache.ImageCacheManager() image_cache_manager._remove_base_file(fname) self.assertTrue(os.path.exists(fname)) self.assertNotEqual(stream.getvalue().find('Failed to remove'), -1)
def generate_x509_cert(user_id, project_id, bits=2048): """Generate and sign a cert for user in project.""" subject = _user_cert_subject(user_id, project_id) with utils.tempdir() as tmpdir: keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) csrfile = os.path.abspath(os.path.join(tmpdir, 'temp.csr')) utils.execute('openssl', 'genrsa', '-out', keyfile, str(bits)) utils.execute('openssl', 'req', '-new', '-key', keyfile, '-out', csrfile, '-batch', '-subj', subject) with open(keyfile) as f: private_key = f.read() with open(csrfile) as f: csr = f.read() (serial, signed_csr) = sign_csr(csr, project_id) fname = os.path.join(ca_folder(project_id), 'newcerts/%s.pem' % serial) cert = {'user_id': user_id, 'project_id': project_id, 'file_name': fname} db.certificate_create(context.get_admin_context(), cert) return (private_key, signed_csr)
def test_can_generate_x509(self): with utils.tempdir() as tmpdir: self.flags(ca_path=tmpdir) crypto.ensure_ca_filesystem() _key, cert_str = crypto.generate_x509_cert('fake', 'fake') project_cert = crypto.fetch_ca(project_id='fake') signed_cert_file = os.path.join(tmpdir, "signed") with open(signed_cert_file, 'w') as keyfile: keyfile.write(cert_str) project_cert_file = os.path.join(tmpdir, "project") with open(project_cert_file, 'w') as keyfile: keyfile.write(project_cert) enc, err = utils.execute('openssl', 'verify', '-CAfile', project_cert_file, '-verbose', signed_cert_file) self.assertFalse(err)
def generate_key_pair(bits=None): with utils.tempdir() as tmpdir: keyfile = os.path.join(tmpdir, 'temp') args = ['ssh-keygen', '-q', '-N', '', '-t', 'rsa', '-f', keyfile, '-C', 'Generated-by-Nova'] if bits is not None: args.extend(['-b', bits]) utils.execute(*args) fingerprint = _generate_fingerprint('%s.pub' % (keyfile)) if not os.path.exists(keyfile): raise exception.FileNotFound(keyfile) with open(keyfile) as f: private_key = f.read() public_key_path = keyfile + '.pub' if not os.path.exists(public_key_path): raise exception.FileNotFound(public_key_path) with open(public_key_path) as f: public_key = f.read() return (private_key, public_key, fingerprint)
def test_modified_policy_reloads(self): with utils.tempdir() as tmpdir: tmpfilename = os.path.join(tmpdir, 'policy') self.flags(policy_file=tmpfilename) # NOTE(uni): context construction invokes policy check to determin # is_admin or not. As a side-effect, policy reset is needed here # to flush existing policy cache. policy.reset() action = "example:test" with open(tmpfilename, "w") as policyfile: policyfile.write('{"example:test": ""}') policy.enforce(self.context, action, self.target) with open(tmpfilename, "w") as policyfile: policyfile.write('{"example:test": "!"}') policy._ENFORCER.load_rules(True) self.assertRaises(exception.PolicyNotAuthorized, policy.enforce, self.context, action, self.target)
def generate_key_pair(bits=None): with utils.tempdir() as tmpdir: keyfile = os.path.join(tmpdir, 'temp') args = [ 'ssh-keygen', '-q', '-N', '', '-t', 'rsa', '-f', keyfile, '-C', 'Generated-by-Nova' ] if bits is not None: args.extend(['-b', bits]) utils.execute(*args) fingerprint = _generate_fingerprint('%s.pub' % (keyfile)) if not os.path.exists(keyfile): raise exception.FileNotFound(keyfile) with open(keyfile) as f: private_key = f.read() public_key_path = keyfile + '.pub' if not os.path.exists(public_key_path): raise exception.FileNotFound(public_key_path) with open(public_key_path) as f: public_key = f.read() return (private_key, public_key, fingerprint)
def test_verify_checksum_disabled(self): self.flags(checksum_base_images=False, group='libvirt') with utils.tempdir() as tmpdir: image_cache_manager, fname = self._check_body(tmpdir, "csum valid") res = image_cache_manager._verify_checksum(self.img, fname) self.assertIsNone(res)
def test_verify_checksum(self): with utils.tempdir() as tmpdir: image_cache_manager, fname = self._check_body(tmpdir, "csum valid") res = image_cache_manager._verify_checksum(self.img, fname) self.assertTrue(res)