def run(test, params, env): """ Test virt-admin client-disconnect 1) Start several virsh connections; 2) disconnect some connections; 3) check whether virsh gives out the correct error messages; 4) check whether srv_clients_info gives out the correct info about the virsh clients. """ num_clients = params.get("num_clients") server_name = params.get("server_name") server_ip = params["server_ip"] = params.get("local_ip") server_user = params["server_user"] = params.get("local_user", "root") server_pwd = params["server_pwd"] = params.get("local_pwd") client_ip = params["client_ip"] = params.get("remote_ip") client_pwd = params["client_pwd"] = params.get("remote_pwd") client_user = params["server_user"] = params.get("remote_user", "root") tls_port = params.get("tls_port", "16514") tls_uri = "qemu+tls://%s:%s/system" % (server_ip, tls_port) tls_obj = None remote_virsh_dargs = {'remote_ip': client_ip, 'remote_user': client_user, 'remote_pwd': client_pwd, 'uri': tls_uri, 'ssh_remote_auth': True} if not server_name: server_name = virt_admin.check_server_name() daemon = utils_libvirtd.Libvirtd("virtproxyd") try: tls_obj = TLSConnection(params) tls_obj.conn_setup() tls_obj.auto_recover = True utils_iptables.Firewall_cmd().add_port(tls_port, 'tcp', permanent=True) clients_instant = [] for _ in range(int(num_clients)): # Under split daemon mode, we can connect to virtproxyd via # remote tcp/tls connections,can not connect to virtproxyd direct # on local host clients_instant.append(virsh.VirshPersistent(**remote_virsh_dargs)) out = virt_admin.srv_clients_list(server_name, ignore_status=True, debug=True) client_id = out.stdout_text.strip().splitlines()[-1].split()[0] result = virt_admin.client_disconnect(server_name, client_id, ignore_status=True, debug=True) if result.exit_status: test.fail("This operation should " "success but failed. output: \n %s" % result) elif result.stdout.decode().strip().split()[1][1:-1] != client_id: test.fail("virt-admin did not " "disconnect the correct client.") finally: daemon.restart() utils_iptables.Firewall_cmd().remove_port(tls_port, 'tcp', permanent=True)
def allow_port_in_fw(server_session): """ Allow the libvirt TLS port in the firewall on the remote server :param server_session: RemoteSession object for server connection :returns: None """ firewalld_port = '16514' firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True)
def open_port_in_iptables(self, port, protocol='tcp', server_dict=None, session=None, cleanup=False): """ Open port in iptables :param ports: port to be opened, these formats are supported for now: 1)4567 2)4567-4587 3)4567:4587 :param protocl: protocol to be opened: 'tcp'|'udp'|'sctp'|'dccp' :param server_dict: dict to create server session: {server_ip, server_user, server_pwd} :param session: session of server to open ports on, None to local host :param cleanup: True to cleanup instead of opening port """ # Check whether firewall-cmd is available use_firewall_cmd = distro.detect().name != "Ubuntu" iptables_func = utils_iptables.Iptables.setup_or_cleanup_iptables_rules try: utils_path.find_command("firewall-cmd") except utils_path.CmdNotFoundError: logging.debug("Using iptables for replacement") use_firewall_cmd = False if use_firewall_cmd: firewall_cmd = utils_iptables.Firewall_cmd(session) if ":" in port: port = "%s-%s" % (port.split(":")[0], port.split(":")[1]) # open ports using firewall_cmd if cleanup: firewall_cmd.remove_port(port, protocol, permanent=True) else: firewall_cmd.add_port(port, protocol, permanent=True) else: if "-" in port: port = "%s:%s" % (port.split("-")[0], port.split("-")[1]) # open migration ports in remote machine using iptables rule = [ "INPUT -p %s -m %s --dport %s -j ACCEPT" % (protocol, protocol, port) ] iptables_func(rule, params=server_dict, cleanup=cleanup) if not cleanup: if session: self.opened_ports_remote.append(port) else: self.opened_ports_local.append(port)
def remove_remote_firewall_port(port, params): """ Remove the port on remote host :param port: port to remove :param params: Dictionary with the test parameters """ server_ip = params.get("server_ip") server_user = params.get("server_user") server_pwd = params.get("server_pwd") remote_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(remote_session) firewall_cmd.remove_port(port, 'tcp', permanent=True) remote_session.close()
def migrate_pre_setup(self, desturi, params, cleanup=False, ports='49152:49216'): """ # Setup before migration, # 1. To enable migration ports using iptables # 2. Turn off SMT for power8 machine in remote machine to migrate :param desturi: uri of destination machine to which VM gets migrated :param params: Test params dict :param cleanup: if True revert back to default setting, used to cleanup :param ports: ports used for allowing migration """ use_firewall_cmd = distro.detect().name != "Ubuntu" iptables_func = utils_iptables.Iptables.setup_or_cleanup_iptables_rules try: utils_path.find_command("firewall-cmd") except utils_path.CmdNotFoundError: logging.debug("Using iptables for replacement") use_firewall_cmd = False if use_firewall_cmd: port_to_add = ports if ":" in ports: port_to_add = "%s-%s" % (ports.split(":")[0], ports.split(":")[1]) else: rule = ["INPUT -p tcp -m tcp --dport %s -j ACCEPT" % ports] try: dest_ip = re.search(r'//.*/', desturi, re.I).group(0).strip('/').strip() source_ip = params.get("migrate_source_host", "").strip() # check whether migrate back to source machine or not if ((desturi == "qemu:///system") or (dest_ip == source_ip)): if use_firewall_cmd: firewall_cmd = utils_iptables.Firewall_cmd() if cleanup: firewall_cmd.remove_port(port_to_add, 'tcp', permanent=True) else: firewall_cmd.add_port(port_to_add, 'tcp', permanent=True) # open migration ports in local machine using firewall_cmd else: # open migration ports in local machine using iptables iptables_func(rule, cleanup=cleanup) # SMT for Power8 machine is turned off for local machine during # test setup else: server_ip = params.get("server_ip", params.get("remote_ip")) server_user = params.get("server_user", params.get("remote_user")) server_pwd = params.get("server_pwd", params.get("remote_pwd")) server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") if use_firewall_cmd: firewall_cmd = utils_iptables.Firewall_cmd(server_session) # open migration ports in remote machine using firewall_cmd if cleanup: firewall_cmd.remove_port(port_to_add, 'tcp', permanent=True) else: firewall_cmd.add_port(port_to_add, 'tcp', permanent=True) else: # open migration ports in remote machine using iptables iptables_func(rule, params=params, cleanup=cleanup) cmd = "grep cpu /proc/cpuinfo | awk '{print $3}' | head -n 1" # Check if remote machine is Power8, if so check for smt state # and turn off if it is on. cmd_output = server_session.cmd_status_output(cmd) server_session.close() if (cmd_output[0] == 0): cmd_output = cmd_output[1].strip().upper() if "POWER8" in cmd_output: test_setup.switch_smt(state="off", params=params) else: raise exceptions.TestError( "Failed to get cpuinfo of remote " "server", cmd_output[1]) except AttributeError: # Negative scenarios will have invalid desturi for which test should # continue pass
def run(test, params, env): """ Test remote access with TCP, TLS connection """ test_dict = dict(params) pattern = test_dict.get("filter_pattern", "") if ('@LIBVIRT' in pattern and distro.detect().name == 'rhel' and int(distro.detect().version) < 8): test.cancel("The test {} is not supported on current OS({}{}<8.0) as " "the keyword @LIBVIRT is not supported by gnutls on this " "OS.".format(test.name, distro.detect().name, distro.detect().version)) vm_name = test_dict.get("main_vm") status_error = test_dict.get("status_error", "no") allowed_dn_str = params.get("tls_allowed_dn_list") if allowed_dn_str: allowed_dn_list = [] if not libvirt_version.version_compare(1, 0, 0): # Reverse the order in the dn list to workaround the # feature changes between RHEL 6 and RHEL 7 dn_list = allowed_dn_str.split(",") dn_list.reverse() allowed_dn_str = ','.join(dn_list) allowed_dn_list.append(allowed_dn_str) test_dict['tls_allowed_dn_list'] = allowed_dn_list transport = test_dict.get("transport") plus = test_dict.get("conn_plus", "+") config_ipv6 = test_dict.get("config_ipv6", "no") tls_port = test_dict.get("tls_port", "") listen_addr = test_dict.get("listen_addr", "0.0.0.0") ssh_port = test_dict.get("ssh_port", "") tcp_port = test_dict.get("tcp_port", "") server_ip = test_dict.get("server_ip") server_user = test_dict.get("server_user") server_pwd = test_dict.get("server_pwd") no_any_config = params.get("no_any_config", "no") sasl_type = test_dict.get("sasl_type", "gssapi") sasl_user_pwd = test_dict.get("sasl_user_pwd") sasl_allowed_users = test_dict.get("sasl_allowed_users") server_cn = test_dict.get("server_cn") custom_pki_path = test_dict.get("custom_pki_path") rm_client_key_cmd = test_dict.get("remove_client_key_cmd") rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd") ca_cn_new = test_dict.get("ca_cn_new") no_verify = test_dict.get("no_verify", "no") ipv6_addr_des = test_dict.get("ipv6_addr_des") tls_sanity_cert = test_dict.get("tls_sanity_cert") restart_libvirtd = test_dict.get("restart_libvirtd", "yes") diff_virt_ver = test_dict.get("diff_virt_ver", "no") driver = test_dict.get("test_driver", "qemu") uri_path = test_dict.get("uri_path", "/system") virsh_cmd = params.get("virsh_cmd", "list") action = test_dict.get("libvirtd_action", "restart") uri_user = test_dict.get("uri_user", "") uri_aliases = test_dict.get("uri_aliases", "") uri_default = test_dict.get("uri_default", "") unix_sock_dir = test_dict.get("unix_sock_dir") mkdir_cmd = test_dict.get("mkdir_cmd") rmdir_cmd = test_dict.get("rmdir_cmd") adduser_cmd = test_dict.get("adduser_cmd") deluser_cmd = test_dict.get("deluser_cmd") auth_conf = test_dict.get("auth_conf") auth_conf_cxt = test_dict.get("auth_conf_cxt") polkit_pkla = test_dict.get("polkit_pkla") polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt") ssh_setup = test_dict.get("ssh_setup", "no") tcp_setup = test_dict.get("tcp_setup", "no") tls_setup = test_dict.get("tls_setup", "no") unix_setup = test_dict.get("unix_setup", "no") ssh_recovery = test_dict.get("ssh_auto_recovery", "yes") tcp_recovery = test_dict.get("tcp_auto_recovery", "yes") tls_recovery = test_dict.get("tls_auto_recovery", "yes") unix_recovery = test_dict.get("unix_auto_recovery", "yes") sasl_allowed_username_list = test_dict.get("sasl_allowed_username_list") auth_unix_rw = test_dict.get("auth_unix_rw") kinit_pwd = test_dict.get("kinit_pwd") test_alias = test_dict.get("test_alias") config_list = [] port = "" # extra URI arguments extra_params = "" # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later objs_list = [] # redirect LIBVIRT_DEBUG log into test log later test_dict["logfile"] = test.logfile # Make sure all of parameters are assigned a valid value check_parameters(test_dict, test) # Make sure libvirtd on remote is running server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") remote_libvirtd = Libvirtd(session=server_session) if not remote_libvirtd.is_running(): logging.debug("start libvirt on remote") res = remote_libvirtd.start() if not res: status, output = server_session.cmd_status_output("journalctl -xe") test.error("Failed to start libvirtd on remote. [status]: %s " "[output]: %s." % (status, output)) server_session.close() if distro.detect().name == 'rhel' and int(distro.detect().version) >= 9: # Update crypto policies to legacy for RHEL>=9 per Bug 1931723 or # https://libguestfs.org/virt-v2v-input-xen.1.html#ssh-authentication crypto_policies = process.run("update-crypto-policies --set LEGACY", ignore_status=False) # only simply connect libvirt daemon then return if no_any_config == "yes": test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path) remote_access(test_dict, test) return # append extra 'pkipath' argument to URI if exists if custom_pki_path: extra_params = "?pkipath=%s" % custom_pki_path # append extra 'no_verify' argument to URI if exists if no_verify == "yes": extra_params = "?no_verify=1" # append extra 'socket' argument to URI if exists if unix_sock_dir: extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir # generate auth.conf and default under the '/etc/libvirt' if auth_conf_cxt and auth_conf: cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf) process.system(cmd, ignore_status=True, shell=True) # generate polkit_pkla and default under the # '/etc/polkit-1/localauthority/50-local.d/' if polkit_pkla_cxt and polkit_pkla: cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla) process.system(cmd, ignore_status=True, shell=True) # generate remote IP if config_ipv6 == "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif config_ipv6 != "yes" and server_cn: remote_ip = server_cn elif config_ipv6 != "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif server_ip and transport != "unix": remote_ip = server_ip else: remote_ip = "" # get URI port if tcp_port != "": port = ":" + tcp_port if tls_port != "": port = ":" + tls_port if ssh_port != "" and not ipv6_addr_des: port = ":" + ssh_port # generate URI uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user, remote_ip, port, uri_path, extra_params) test_dict["uri"] = uri logging.debug("The final test dict:\n<%s>", test_dict) if virsh_cmd == "start" and transport != "unix": session = remote.wait_for_login("ssh", server_ip, "22", "root", server_pwd, "#") cmd = "virsh domstate %s" % vm_name status, output = session.cmd_status_output(cmd) if status: session.close() test.cancel(output) session.close() try: # setup IPv6 if config_ipv6 == "yes": ipv6_obj = IPv6Manager(test_dict) objs_list.append(ipv6_obj) ipv6_obj.setup() # compare libvirt version if needs if diff_virt_ver == "yes": compare_virt_version(server_ip, server_user, server_pwd, test) # setup SSH if (transport == "ssh" or ssh_setup == "yes") and sasl_type != "plain": if not test_dict.get("auth_pwd"): ssh_obj = SSHConnection(test_dict) if ssh_recovery == "yes": objs_list.append(ssh_obj) # setup test environment ssh_obj.conn_setup() else: # To access to server with password, # cleanup authorized_keys on remote ssh_pubkey_file = "/root/.ssh/id_rsa.pub" if (os.path.exists("/root/.ssh/id_rsa") and os.path.exists(ssh_pubkey_file)): remote_file_obj = remote.RemoteFile(address=server_ip, client='scp', username=server_user, password=server_pwd, port='22', remote_path="/root/.ssh/authorized_keys") with open(ssh_pubkey_file, 'r') as fd: line = fd.read().split()[-1].rstrip('\n') line = ".*" + line remote_file_obj.remove([line]) objs_list.append(remote_file_obj) # setup TLS if transport == "tls" or tls_setup == "yes": tls_obj = TLSConnection(test_dict) if tls_recovery == "yes": objs_list.append(tls_obj) # reserve cert path tmp_dir = tls_obj.tmp_dir # setup test environment tls_obj.conn_setup() # setup TCP if transport == "tcp" or tcp_setup == "yes": tcp_obj = TCPConnection(test_dict) if tcp_recovery == "yes": objs_list.append(tcp_obj) # setup test environment tcp_obj.conn_setup() # create a directory if needs if mkdir_cmd: process.system(mkdir_cmd, ignore_status=True, shell=True) # setup UNIX if transport == "unix" or unix_setup == "yes" or sasl_type == "plain": unix_obj = UNIXConnection(test_dict) if unix_recovery == "yes": objs_list.append(unix_obj) # setup test environment unix_obj.conn_setup() # need to restart libvirt service for negative testing if restart_libvirtd == "no": remotely_control_libvirtd(server_ip, server_user, server_pwd, action, status_error) # check TCP/IP listening by service if restart_libvirtd != "no" and transport != "unix": service = 'libvirtd' if transport == "ssh": service = 'ssh' check_listening_port_remote_by_service(server_ip, server_user, server_pwd, service, port, listen_addr) # open the tls/tcp listening port on server if transport in ["tls", "tcp"]: firewalld_port = port[1:] server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True) server_session.close() if 'inv_transport' in test_dict: transport = test_dict['inv_transport'] uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user, remote_ip, port, uri_path, extra_params) test_dict["uri"] = uri config_list = [] if uri_aliases: uri_config = change_libvirtconf_on_client( {'uri_aliases': uri_aliases}) config_list.append(uri_config) test_dict["uri"] = test_alias if uri_default: test_dict["uri"] = "" # Delete the default URI environment variable to prevent overriding del os.environ['LIBVIRT_DEFAULT_URI'] uri_config = change_libvirtconf_on_client( {'uri_default': uri_default}) config_list.append(uri_config) ret = virsh.command('uri', debug=True) if uri_default.strip('"') in ret.stdout_text: logging.debug("Virsh output as expected.") else: test.fail("Expected virsh output: {} not found in:{}".format( uri_default.strip('"'), ret.stdout_text)) # remove client certifications if exist, only for TLS negative testing if rm_client_key_cmd: process.system(rm_client_key_cmd, ignore_status=True, shell=True) if rm_client_cert_cmd: process.system(rm_client_cert_cmd, ignore_status=True, shell=True) # add user to specific group if adduser_cmd: process.system(adduser_cmd, ignore_status=True, shell=True) # change /etc/pki/libvirt/servercert.pem then # restart libvirt service on the remote host if tls_sanity_cert == "no" and ca_cn_new: test_dict['ca_cn'] = ca_cn_new test_dict['scp_new_cacert'] = 'no' tls_obj_new = TLSConnection(test_dict) test_dict['tls_obj_new'] = tls_obj_new # only setup new CA and server tls_obj_new.conn_setup(True, False) # obtain and cache a ticket if kinit_pwd and sasl_type == 'gssapi' and auth_unix_rw == 'sasl': username_list = json.loads(sasl_allowed_username_list) for username in username_list: kinit_cmd = "echo '%s' | kinit %s" % (kinit_pwd, username) process.system(kinit_cmd, ignore_status=True, shell=True) # setup SASL certification # From libvirt-3.2.0, the default sasl change from # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded. # More details: https://libvirt.org/auth.html#ACL_server_kerberos if sasl_user_pwd and sasl_type in ['digest-md5', 'plain']: # covert string tuple and list to python data type sasl_user_pwd = eval(sasl_user_pwd) if sasl_allowed_users: sasl_allowed_users = eval(sasl_allowed_users) # create a sasl user sasl_obj = SASL(test_dict) objs_list.append(sasl_obj) sasl_obj.setup() for sasl_user, sasl_pwd in sasl_user_pwd: # need't authentication if the auth.conf is configured by user if not auth_conf: if sasl_type == 'plain': test_dict["auth_pwd"] = server_pwd pass else: test_dict["auth_user"] = sasl_user test_dict["auth_pwd"] = sasl_pwd logging.debug("sasl_user, sasl_pwd = " "(%s, %s)", sasl_user, sasl_pwd) if sasl_allowed_users and sasl_user not in sasl_allowed_users: test_dict["status_error"] = "yes" patterns_extra_dict = {"authentication name": sasl_user, "enter your password": sasl_pwd} test_dict["patterns_extra_dict"] = patterns_extra_dict remote_access(test_dict, test) else: if not uri_default: remote_access(test_dict, test) finally: # recovery test environment # Destroy the VM after all test are done for config in config_list: restore_libvirtconf_on_client(config) cleanup(objs_list) if vm_name: vm = env.get_vm(vm_name) if vm and vm.is_alive(): vm.destroy(gracefully=False) if transport in ["tcp", "tls"] and 'firewalld_port' in locals(): server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.remove_port(firewalld_port, 'tcp', permanent=True) server_session.close() if rmdir_cmd: process.system(rmdir_cmd, ignore_status=True, shell=True) if deluser_cmd: process.system(deluser_cmd, ignore_status=True, shell=True) if auth_conf and os.path.isfile(auth_conf): os.unlink(auth_conf) if polkit_pkla and os.path.isfile(polkit_pkla): os.unlink(polkit_pkla)
def run(test, params, env): """ Test TLS connection priorities with remote machine. """ server_ip = params.get("server_ip") server_user = params.get("server_user") server_pwd = params.get("server_pwd") tls_port = params.get("tls_port", "16514") ssl_v3 = params.get("priority_ssl_v3_only") ssl_inv = params.get("priority_ssl_invalid") tls_inv = params.get("priority_tls_invalid") no_ssl_v3 = params.get("priority_no_ssl_v3") wrong_message = params.get("wrong_priorities_message").split(',') invalid_message = params.get("invalid_priorities_message").split(',') welcome_message = params.get("successful_message").split(',') uri = "qemu+tls://{}" remote_update_session = None # Initial Setup - this part is the longest and always required part of the # test and therefore it is not effective to divide this test into smaller # parts that would take much longer in sum. # Create connection with the server server_session = create_session_on_remote(params) # Make sure the Libvirtd is running on remote remote_libvirtd = utils_libvirtd.Libvirtd(session=server_session) if not remote_libvirtd.is_running(): res = remote_libvirtd.start() if not res: status, output = server_session.cmd_status_output("journalctl -xe") test.error("Failed to start libvirtd on remote. [status]: %s " "[output]: %s." % (status, output)) # setup TLS tls_obj = TLSConnection(params) # setup test environment tls_obj.conn_setup() # Open the tls/tcp listening port on server firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.add_port(tls_port, 'tcp', permanent=True) server_session.close() # Check which version to use for TLS v1.X ssl_check = process.run( 'openssl s_client -connect {}:16514 -tls1_1'.format(server_ip), ignore_status=True) if ssl_check.exit_status: logging.debug('TLSv1.1 not supported, use TLS v1.2 instead') tls_v1 = params.get("priority_tls_v1_2_only") else: # Use TLS v1.0 tls_v1 = params.get("priority_tls_v1_only") # Update TLS priority on remote replacements = { r'#tls_priority=".*?"': 'tls_priority="{}"'.format(params['remote_tls_priority']) } # DO NOT DELETE remote_update_session as it destroys changes applied by the # method remote_libvirtdconf.sub_else_add - cleanup called when the instance # is destroyed remote_update_session = change_parameter_on_remote(params, replacements) # Restart Remote Libvirtd " remotely_control_libvirtd(server_ip, server_user, server_pwd, 'restart') config = None try: # Phase I - test via libvirt.conf on client # TLS priority set to SSLv3 only for client via libvirt.conf new_tls_priority = {'tls_priority': '"{}"'.format(ssl_v3)} config = change_libvirtconf_on_client(new_tls_priority) # Connect to hypervisor uri_path = server_ip + '/system' connect_dict = { 'uri': uri.format(uri_path), 'cmd': "", 'pass_message_list': wrong_message, 'expect_error': True, } test_pass = connect_to_server_hypervisor(connect_dict) # Restore if pass if test_pass: config.restore() config = None else: test.fail( 'TLS priorities test failed for case when client supports' ' SSLv3 only and server does not support SSLv3 only.') # TLS priority set to TLS1.0 only for client via libvirt.conf new_tls_priority = {'tls_priority': '"{}"'.format(tls_v1)} config = change_libvirtconf_on_client(new_tls_priority) # Remove SSLv3.0 support via URI uri_path = server_ip + '/system' + '?tls_priority={}'.format(no_ssl_v3) connect_dict['uri'] = uri.format(uri_path) connect_dict['pass_message_list'] = welcome_message connect_dict['expect_error'] = False test_pass = connect_to_server_hypervisor(connect_dict) if test_pass: config.restore() config = None else: test.fail( 'TLS priorities test failed for case when client supports' ' TLSv1.X only and server does not support SSLv3 only.') # Pass invalid SSL priority new_tls_priority = {'tls_priority': '"{}"'.format(ssl_inv)} config = change_libvirtconf_on_client(new_tls_priority) uri_path = server_ip + '/system' connect_dict['uri'] = uri.format(uri_path) connect_dict['pass_message_list'] = invalid_message connect_dict['expect_error'] = True test_pass = connect_to_server_hypervisor(connect_dict) if test_pass: config.restore() config = None else: test.fail( 'TLS priorities test failed for case when client supports' ' SSLv4.0 which is invalid.') # Phase II - test via URI on client uri_path = server_ip + '/system' + '?tls_priority={}'.format(ssl_v3) connect_dict['uri'] = uri.format(uri_path) connect_dict['pass_message_list'] = wrong_message connect_dict['expect_error'] = True test_pass = connect_to_server_hypervisor(connect_dict) if not test_pass: test.fail('TLS priorities test failed for case when the client ' 'supports SSLv3 only by URI and the server does not ' 'support SSLv3 only.') uri_path = server_ip + '/system' + '?tls_priority={}'.format(tls_v1) connect_dict['uri'] = uri.format(uri_path) connect_dict['pass_message_list'] = welcome_message connect_dict['expect_error'] = False test_pass = connect_to_server_hypervisor(connect_dict) if not test_pass: test.fail('TLS priorities test failed for case when the client ' 'supports TLSv1.X only by URI and the server does not ' 'support SSLv3 only.') uri_path = server_ip + '/system' + '?tls_priority={}'.format(tls_inv) connect_dict['uri'] = uri.format(uri_path) connect_dict['pass_message_list'] = invalid_message connect_dict['expect_error'] = True test_pass = connect_to_server_hypervisor(connect_dict) if not test_pass: test.fail('TLS priorities test failed for case when the client ' 'supports SSLv4.0 by URI which is invalid.') finally: # Reset Firewall server_session = create_session_on_remote(params) firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.remove_port(tls_port, 'tcp') server_session.close() if config: config.restore() # Restore config on remote if remote_update_session: del remote_update_session
def run(test, params, env): """ Test remote access with TCP, TLS connection """ test_dict = dict(params) vm_name = test_dict.get("main_vm") status_error = test_dict.get("status_error", "no") allowed_dn_str = params.get("tls_allowed_dn_list") if allowed_dn_str: allowed_dn_list = [] if not libvirt_version.version_compare(1, 0, 0): # Reverse the order in the dn list to workaround the # feature changes between RHEL 6 and RHEL 7 dn_list = allowed_dn_str.split(",") dn_list.reverse() allowed_dn_str = ','.join(dn_list) allowed_dn_list.append(allowed_dn_str) test_dict['tls_allowed_dn_list'] = allowed_dn_list transport = test_dict.get("transport") plus = test_dict.get("conn_plus", "+") config_ipv6 = test_dict.get("config_ipv6", "no") tls_port = test_dict.get("tls_port", "") listen_addr = test_dict.get("listen_addr", "0.0.0.0") ssh_port = test_dict.get("ssh_port", "") tcp_port = test_dict.get("tcp_port", "") server_ip = test_dict.get("server_ip") server_user = test_dict.get("server_user") server_pwd = test_dict.get("server_pwd") no_any_config = params.get("no_any_config", "no") sasl_type = test_dict.get("sasl_type", "gssapi") sasl_user_pwd = test_dict.get("sasl_user_pwd") sasl_allowed_users = test_dict.get("sasl_allowed_users") server_cn = test_dict.get("server_cn") custom_pki_path = test_dict.get("custom_pki_path") rm_client_key_cmd = test_dict.get("remove_client_key_cmd") rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd") ca_cn_new = test_dict.get("ca_cn_new") no_verify = test_dict.get("no_verify", "no") ipv6_addr_des = test_dict.get("ipv6_addr_des") tls_sanity_cert = test_dict.get("tls_sanity_cert") restart_libvirtd = test_dict.get("restart_libvirtd", "yes") diff_virt_ver = test_dict.get("diff_virt_ver", "no") driver = test_dict.get("test_driver", "qemu") uri_path = test_dict.get("uri_path", "/system") virsh_cmd = params.get("virsh_cmd", "list") action = test_dict.get("libvirtd_action", "restart") uri_user = test_dict.get("uri_user", "") unix_sock_dir = test_dict.get("unix_sock_dir") mkdir_cmd = test_dict.get("mkdir_cmd") rmdir_cmd = test_dict.get("rmdir_cmd") adduser_cmd = test_dict.get("adduser_cmd") deluser_cmd = test_dict.get("deluser_cmd") auth_conf = test_dict.get("auth_conf") auth_conf_cxt = test_dict.get("auth_conf_cxt") polkit_pkla = test_dict.get("polkit_pkla") polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt") ssh_setup = test_dict.get("ssh_setup", "no") tcp_setup = test_dict.get("tcp_setup", "no") tls_setup = test_dict.get("tls_setup", "no") unix_setup = test_dict.get("unix_setup", "no") ssh_recovery = test_dict.get("ssh_auto_recovery", "yes") tcp_recovery = test_dict.get("tcp_auto_recovery", "yes") tls_recovery = test_dict.get("tls_auto_recovery", "yes") unix_recovery = test_dict.get("unix_auto_recovery", "yes") port = "" # extra URI arguments extra_params = "" # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later objs_list = [] # redirect LIBVIRT_DEBUG log into test log later test_dict["logfile"] = test.logfile # Make sure all of parameters are assigned a valid value check_parameters(test_dict, test) # only simply connect libvirt daemon then return if no_any_config == "yes": test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path) remote_access(test_dict, test) return # append extra 'pkipath' argument to URI if exists if custom_pki_path: extra_params = "?pkipath=%s" % custom_pki_path # append extra 'no_verify' argument to URI if exists if no_verify == "yes": extra_params = "?no_verify=1" # append extra 'socket' argument to URI if exists if unix_sock_dir: extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir # generate auth.conf and default under the '/etc/libvirt' if auth_conf_cxt and auth_conf: cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf) process.system(cmd, ignore_status=True, shell=True) # generate polkit_pkla and default under the # '/etc/polkit-1/localauthority/50-local.d/' if polkit_pkla_cxt and polkit_pkla: cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla) process.system(cmd, ignore_status=True, shell=True) # generate remote IP if config_ipv6 == "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif config_ipv6 != "yes" and server_cn: remote_ip = server_cn elif config_ipv6 != "yes" and ipv6_addr_des: remote_ip = "[%s]" % ipv6_addr_des elif server_ip and transport != "unix": remote_ip = server_ip else: remote_ip = "" # get URI port if tcp_port != "": port = ":" + tcp_port if tls_port != "": port = ":" + tls_port if ssh_port != "" and not ipv6_addr_des: port = ":" + ssh_port # generate URI uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user, remote_ip, port, uri_path, extra_params) test_dict["uri"] = uri logging.debug("The final test dict:\n<%s>", test_dict) if virsh_cmd == "start" and transport != "unix": session = remote.wait_for_login("ssh", server_ip, "22", "root", server_pwd, "#") cmd = "virsh domstate %s" % vm_name status, output = session.cmd_status_output(cmd) if status: session.close() test.cancel(output) session.close() try: # setup IPv6 if config_ipv6 == "yes": ipv6_obj = IPv6Manager(test_dict) objs_list.append(ipv6_obj) ipv6_obj.setup() # compare libvirt version if needs if diff_virt_ver == "yes": compare_virt_version(server_ip, server_user, server_pwd, test) # setup SSH if transport == "ssh" or ssh_setup == "yes": if not test_dict.get("auth_pwd"): ssh_obj = SSHConnection(test_dict) if ssh_recovery == "yes": objs_list.append(ssh_obj) # setup test environment ssh_obj.conn_setup() # setup TLS if transport == "tls" or tls_setup == "yes": tls_obj = TLSConnection(test_dict) if tls_recovery == "yes": objs_list.append(tls_obj) # reserve cert path tmp_dir = tls_obj.tmp_dir # setup test environment if tls_sanity_cert == "no": # only setup CA and client tls_obj.conn_setup(False, True) else: # setup CA, server and client tls_obj.conn_setup() # setup TCP if transport == "tcp" or tcp_setup == "yes": tcp_obj = TCPConnection(test_dict) if tcp_recovery == "yes": objs_list.append(tcp_obj) # setup test environment tcp_obj.conn_setup() # create a directory if needs if mkdir_cmd: process.system(mkdir_cmd, ignore_status=True, shell=True) # setup UNIX if transport == "unix" or unix_setup == "yes": unix_obj = UNIXConnection(test_dict) if unix_recovery == "yes": objs_list.append(unix_obj) # setup test environment unix_obj.conn_setup() # need to restart libvirt service for negative testing if restart_libvirtd == "no": remotely_control_libvirtd(server_ip, server_user, server_pwd, action, status_error) # check TCP/IP listening by service if restart_libvirtd != "no" and transport != "unix": service = 'libvirtd' if transport == "ssh": service = 'ssh' check_listening_port_remote_by_service(server_ip, server_user, server_pwd, service, port, listen_addr) # open the tls/tcp listening port on server if transport in ["tls", "tcp"]: firewalld_port = port[1:] server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True) server_session.close() # remove client certifications if exist, only for TLS negative testing if rm_client_key_cmd: process.system(rm_client_key_cmd, ignore_status=True, shell=True) if rm_client_cert_cmd: process.system(rm_client_cert_cmd, ignore_status=True, shell=True) # add user to specific group if adduser_cmd: process.system(adduser_cmd, ignore_status=True, shell=True) # change /etc/pki/libvirt/servercert.pem then # restart libvirt service on the remote host if tls_sanity_cert == "no" and ca_cn_new: test_dict['ca_cn'] = ca_cn_new test_dict['ca_cakey_path'] = tmp_dir test_dict['scp_new_cacert'] = 'no' tls_obj_new = TLSConnection(test_dict) test_dict['tls_obj_new'] = tls_obj_new # only setup new CA and server tls_obj_new.conn_setup(True, False) # setup SASL certification # From libvirt-3.2.0, the default sasl change from # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded. # More details: https://libvirt.org/auth.html#ACL_server_kerberos if sasl_user_pwd and sasl_type == 'digest-md5': # covert string tuple and list to python data type sasl_user_pwd = eval(sasl_user_pwd) if sasl_allowed_users: sasl_allowed_users = eval(sasl_allowed_users) # create a sasl user sasl_obj = SASL(test_dict) objs_list.append(sasl_obj) sasl_obj.setup() for sasl_user, sasl_pwd in sasl_user_pwd: # need't authentication if the auth.conf is configured by user if not auth_conf: test_dict["auth_user"] = sasl_user test_dict["auth_pwd"] = sasl_pwd logging.debug("sasl_user, sasl_pwd = " "(%s, %s)", sasl_user, sasl_pwd) if sasl_allowed_users and sasl_user not in sasl_allowed_users: test_dict["status_error"] = "yes" patterns_extra_dict = {"authentication name": sasl_user} test_dict["patterns_extra_dict"] = patterns_extra_dict remote_access(test_dict, test) else: remote_access(test_dict, test) finally: # recovery test environment # Destroy the VM after all test are done cleanup(objs_list) if vm_name: vm = env.get_vm(vm_name) if vm and vm.is_alive(): vm.destroy(gracefully=False) if transport in ["tcp", "tls"]: server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") firewall_cmd = utils_iptables.Firewall_cmd(server_session) firewall_cmd.remove_port(firewalld_port, 'tcp', permanent=True) server_session.close() if rmdir_cmd: process.system(rmdir_cmd, ignore_status=True, shell=True) if deluser_cmd: process.system(deluser_cmd, ignore_status=True, shell=True) if auth_conf and os.path.isfile(auth_conf): os.unlink(auth_conf) if polkit_pkla and os.path.isfile(polkit_pkla): os.unlink(polkit_pkla)
def run(test, params, env): """ Test virt-admin server-clients-set 2) Change max_clients to a new value; 3) get the current clients info; 4) check whether the clients info is correct; 5) try to connect other client onto the server; 6) check whether the above connection status is correct. """ def clients_info(server): """ check the attributes by server-clients-set. 1) get the output returned by server-clients-set; 2) split the output to get a dictionary of those attributes; :params server: print the info of the clients connecting to this server :return: a dict obtained by transforming the result_info """ result_info = virt_admin.srv_clients_info(server, ignore_status=True, debug=True) out = result_info.stdout_text.strip().splitlines() out_split = [item.split(':') for item in out] out_dict = dict([[item[0].strip(), item[1].strip()] for item in out_split]) return out_dict def chk_connect_to_daemon(connect_able): try: virsh_instance.append(virsh.VirshPersistent(**remote_virsh_dargs)) except Exception as info: if connect_able == "yes": test.fail("Connection to daemon is not success, error:\n %s" % info) else: logging.info("Connections to daemon should not success, " "this is a correct test result!") else: if connect_able == "yes": logging.info("Connections to daemon is successful, " "this is a correct test result!") else: test.fail("error: Connection to daemon should not success! " "Check the attributes.") server_name = params.get("server_name") is_positive = params.get("is_positive") == "yes" options_ref = params.get("options_ref") nclients_max = params.get("nclients_maxi") nclients = params.get("nclients") nclients_unauth_max = params.get("nclients_unauth_maxi") connect_able = params.get("connect_able") options_test_together = params.get("options_test_together") server_ip = params["server_ip"] = params.get("local_ip") server_user = params["server_user"] = params.get("local_user", "root") server_pwd = params["server_pwd"] = params.get("local_pwd") client_ip = params["client_ip"] = params.get("remote_ip") client_pwd = params["client_pwd"] = params.get("remote_pwd") client_user = params["server_user"] = params.get("remote_user", "root") tls_port = params.get("tls_port", "16514") tls_uri = "qemu+tls://%s:%s/system" % (server_ip, tls_port) tls_obj = None remote_virsh_dargs = { 'remote_ip': client_ip, 'remote_user': client_user, 'remote_pwd': client_pwd, 'uri': tls_uri, 'ssh_remote_auth': True } if not server_name: server_name = virt_admin.check_server_name() config = virt_admin.managed_daemon_config() daemon = utils_libvirtd.Libvirtd("virtproxyd") virsh_instance = [] try: if nclients: tls_obj = TLSConnection(params) tls_obj.conn_setup() tls_obj.auto_recover = True utils_iptables.Firewall_cmd().add_port(tls_port, 'tcp', permanent=True) if options_ref: if "max-clients" in options_ref: if nclients: if int(nclients_max) > int(nclients): config.max_clients = nclients config.max_anonymous_clients = nclients_unauth_max daemon.restart() for _ in range(int(nclients)): virsh_instance.append( virsh.VirshPersistent(**remote_virsh_dargs)) result = virt_admin.srv_clients_set( server_name, max_clients=nclients_max, ignore_status=True, debug=True) elif int(nclients_max) <= int(nclients): for _ in range(int(nclients)): virsh_instance.append( virsh.VirshPersistent(**remote_virsh_dargs)) result = virt_admin.srv_clients_set( server_name, max_clients=nclients_max, max_unauth_clients=nclients_unauth_max, ignore_status=True, debug=True) else: result = virt_admin.srv_clients_set( server_name, max_clients=nclients_max, ignore_status=True, debug=True) elif "max-unauth-clients" in options_ref: result = virt_admin.srv_clients_set( server_name, max_unauth_clients=nclients_unauth_max, ignore_status=True, debug=True) elif options_test_together: result = virt_admin.srv_clients_set( server_name, max_clients=nclients_max, max_unauth_clients=nclients_unauth_max, ignore_status=True, debug=True) outdict = clients_info(server_name) if result.exit_status: if is_positive: test.fail("This operation should success " "but failed! output:\n%s " % result) else: logging.debug("This failure is expected!") else: if is_positive: if options_ref: if "max-clients" in options_ref: if outdict["nclients_max"] != nclients_max: test.fail("attributes set by server-clients-set " "is not correct!") if nclients: chk_connect_to_daemon(connect_able) elif "max_unauth_clients" in options_ref: if outdict[ "nclients_unauth_max"] != nclients_unauth_max: test.fail("attributes set by server-clients-set " "is not correct!") elif options_test_together: if (outdict["nclients_max"] != nclients_max or outdict["nclients_unauth_max"] != nclients_unauth_max): test.fail("attributes set by server-clients-set " "is not correct!") else: test.fail("This is a negative case, should get failure.") finally: for session in virsh_instance: session.close_session() config.restore() daemon.restart() utils_iptables.Firewall_cmd().remove_port(tls_port, 'tcp', permanent=True)
def run(test, params, env): """ Test virt-admin srv-clients-info 1) Change the clients related parameters in daemon config file; 2) Restart daemon; 3) Start several virsh connections; 4) Check whether the parameters value listed by srv-clients-info are the same with the above settings. """ max_clients = params.get("max_clients") max_anonymous_clients = params.get("max_anonymous_clients") server_name = params.get("server_name") num_clients = params.get("num_clients") server_ip = params["server_ip"] = params.get("local_ip") server_user = params["server_user"] = params.get("local_user", "root") server_pwd = params["server_pwd"] = params.get("local_pwd") client_ip = params["client_ip"] = params.get("remote_ip") client_pwd = params["client_pwd"] = params.get("remote_pwd") client_user = params["server_user"] = params.get("remote_user", "root") tls_port = params.get("tls_port", "16514") tls_uri = "qemu+tls://%s:%s/system" % (server_ip, tls_port) tls_obj = None remote_virsh_dargs = {'remote_ip': client_ip, 'remote_user': client_user, 'remote_pwd': client_pwd, 'uri': tls_uri, 'ssh_remote_auth': True} if not server_name: server_name = virt_admin.check_server_name() config = virt_admin.managed_daemon_config() daemon = utils_libvirtd.Libvirtd("virtproxyd") try: config.max_clients = max_clients config.max_anonymous_clients = max_anonymous_clients daemon.restart() tls_obj = TLSConnection(params) tls_obj.conn_setup() tls_obj.auto_recover = True utils_iptables.Firewall_cmd().add_port(tls_port, 'tcp', permanent=True) clients_instant = [] for _ in range(int(num_clients)): # Under split daemon mode, we can connect to virtproxyd via # remote tls/tcp connections,can not connect to virtproxyd direct # on local host clients_instant.append(virsh.VirshPersistent(**remote_virsh_dargs)) result = virt_admin.srv_clients_info(server_name, ignore_status=True, debug=True) output = result.stdout_text.strip().splitlines() out_split = [item.split(':') for item in output] out_dict = dict([[item[0].strip(), item[1].strip()] for item in out_split]) if result.exit_status: test.fail("This operation should success " "but failed. Output:\n %s" % result) else: if not (out_dict["nclients_max"] == max_clients and out_dict["nclients_unauth_max"] == max_anonymous_clients): test.fail("attributes info listed by " "srv-clients-info is not correct.") if not out_dict["nclients"] == num_clients: test.fail("the number of clients connect to daemon " "is not correct.") finally: config.restore() daemon.restart() utils_iptables.Firewall_cmd().remove_port(tls_port, 'tcp', permanent=True)