def _assert_args(resource_group, vm_name, ssh_ip): if not (resource_group or vm_name or ssh_ip): raise util.CLIError("The VM must be specified by --ip or --resource-group and --vm-name/--name") if resource_group and not vm_name or vm_name and not resource_group: raise util.CLIError("--resource-group and --vm-name/--name must be provided together") if ssh_ip and (vm_name or resource_group): raise util.CLIError("--ip cannot be used with --resource-group or --vm-name/--name")
def _check_public_private_files(public_key_file, private_key_file): ssh_dir_parts = ["~", ".ssh"] public_key_file = public_key_file or os.path.expanduser(os.path.join(*ssh_dir_parts, "id_rsa.pub")) private_key_file = private_key_file or os.path.expanduser(os.path.join(*ssh_dir_parts, "id_rsa")) if not os.path.isfile(public_key_file): raise util.CLIError(f"Pulic key file {public_key_file} not found") if not os.path.isfile(private_key_file): raise util.CLIError(f"Private key file {private_key_file} not found") return public_key_file, private_key_file
def _do_ssh_op(cmd, resource_group, vm_name, ssh_ip, public_key_file, private_key_file, use_private_ip, op_call): _assert_args(resource_group, vm_name, ssh_ip) public_key_file, private_key_file = _check_or_create_public_private_files(public_key_file, private_key_file) ssh_ip = ssh_ip or ip_utils.get_ssh_ip(cmd, resource_group, vm_name, use_private_ip) if not ssh_ip: if not use_private_ip: raise util.CLIError(f"VM '{vm_name}' does not have a public IP address to SSH to") raise util.CLIError(f"VM '{vm_name}' does not have a public or private IP address to SSH to") cert_file, username = _get_and_write_certificate(cmd, public_key_file, None) op_call(ssh_ip, username, cert_file, private_key_file)
def _get_modulus_exponent(public_key_file): if not os.path.isfile(public_key_file): raise util.CLIError(f"Public key file '{public_key_file}' was not found") with open(public_key_file, 'r') as f: public_key_text = f.read() parser = rsa_parser.RSAParser() try: parser.parse(public_key_text) except Exception as e: raise util.CLIError(f"Could not parse public key. Error: {str(e)}") modulus = parser.modulus exponent = parser.exponent return modulus, exponent
def _check_or_create_public_private_files(public_key_file, private_key_file): # If nothing is passed in create a temporary directory with a ephemeral keypair if not public_key_file and not private_key_file: temp_dir = tempfile.mkdtemp(prefix="aadsshcert") public_key_file = os.path.join(temp_dir, "id_rsa.pub") private_key_file = os.path.join(temp_dir, "id_rsa") ssh_utils.create_ssh_keyfile(private_key_file) if not os.path.isfile(public_key_file): raise util.CLIError(f"Public key file {public_key_file} not found") # The private key is not required as the user may be using a keypair # stored in ssh-agent (and possibly in a hardware token) if private_key_file: if not os.path.isfile(private_key_file): raise util.CLIError(f"Private key file {private_key_file} not found") return public_key_file, private_key_file
def _do_ssh_op(cmd, resource_group, vm_name, ssh_ip, public_key_file, private_key_file, op_call): _assert_args(resource_group, vm_name, ssh_ip) public_key_file, private_key_file = _check_public_private_files(public_key_file, private_key_file) ssh_ip = ssh_ip or ip_utils.get_ssh_ip(cmd, resource_group, vm_name) if not ssh_ip: raise util.CLIError(f"VM '{vm_name}' does not have a public IP address to SSH to") scopes = ["https://pas.windows.net/CheckMyAccess/Linux/user_impersonation"] data = _prepare_jwk_data(public_key_file) from azure.cli.core._profile import Profile profile = Profile(cli_ctx=cmd.cli_ctx) username, certificate = profile.get_msal_token(scopes, data) cert_file = _write_cert_file(public_key_file, certificate) op_call(ssh_ip, username, cert_file, private_key_file)
def _get_ssh_path(ssh_command="ssh"): ssh_path = ssh_command if platform.system() == 'Windows': arch_data = platform.architecture() is_32bit = arch_data[0] == '32bit' sys_path = 'SysNative' if is_32bit else 'System32' system_root = os.environ['SystemRoot'] system32_path = os.path.join(system_root, sys_path) ssh_path = os.path.join(system32_path, "openSSH", (ssh_command + ".exe")) logger.debug("Platform architecture: %s", str(arch_data)) logger.debug("System Root: %s", system_root) logger.debug("Attempting to run ssh from path %s", ssh_path) if not os.path.isfile(ssh_path): raise util.CLIError("Could not find " + ssh_command + ".exe. Is the OpenSSH client installed?") return ssh_path