Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ These and the sudo configuration needs to be prepared by the administrator.
Arguments:
- address (str): hostname of the remote system
- username (str): username used by SSH
- password (str, default=""): password used by SSH
- password (str, default=None): optional, password used by SSH
- port (int, default=22): port used by SSH

Used by:
Expand Down
15 changes: 9 additions & 6 deletions labgrid/driver/sshdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SSHDriver(CommandMixin, Driver, CommandProtocol, FileTransferProtocol):
explicit_sftp_mode = attr.ib(default=False, validator=attr.validators.instance_of(bool))
explicit_scp_mode = attr.ib(default=False, validator=attr.validators.instance_of(bool))
username = attr.ib(default="", validator=attr.validators.instance_of(str))
password = attr.ib(default="", validator=attr.validators.instance_of(str))
password = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(str)))

def __attrs_post_init__(self):
super().__attrs_post_init__()
Expand All @@ -57,7 +57,9 @@ def _get_username(self):

def _get_password(self):
"""Get the password from this class or from NetworkService"""
return self.password or self.networkservice.password
if self.password is not None:
return self.password
return self.networkservice.password

def on_activate(self):
self.ssh_prefix = ["-o", "LogLevel=ERROR"]
Expand All @@ -66,7 +68,7 @@ def on_activate(self):
if self.target.env:
keyfile_path = self.target.env.config.resolve_path(self.keyfile)
self.ssh_prefix += ["-i", keyfile_path ]
if not self._get_password():
if self._get_password() is None:
self.ssh_prefix += ["-o", "PasswordAuthentication=no"]

self.control = self._start_own_master()
Expand Down Expand Up @@ -136,14 +138,15 @@ def _start_own_master_once(self, timeout):

env = os.environ.copy()
pass_file = ''
if self._get_password():
password = self._get_password()
if password is not None:
fd, pass_file = tempfile.mkstemp()
os.fchmod(fd, stat.S_IRWXU)
#with openssh>=8.4 SSH_ASKPASS_REQUIRE can be used to force SSH_ASK_PASS
#openssh<8.4 requires the DISPLAY var and a detached process with start_new_session=True
env = {'SSH_ASKPASS': pass_file, 'DISPLAY':'', 'SSH_ASKPASS_REQUIRE':'force'}
with open(fd, 'w') as f:
f.write("#!/bin/sh\necho " + shlex.quote(self._get_password()))
f.write("#!/bin/sh\necho " + shlex.quote(password))

self.process = subprocess.Popen(args, env=env,
stdout=subprocess.PIPE,
Expand Down Expand Up @@ -180,7 +183,7 @@ def _start_own_master_once(self, timeout):
f"Subprocess timed out [{subprocess_timeout}s] while executing {args}",
)
finally:
if self._get_password() and os.path.exists(pass_file):
if self._get_password() is not None and os.path.exists(pass_file):
os.remove(pass_file)

if not os.path.exists(control):
Expand Down
2 changes: 1 addition & 1 deletion labgrid/resource/networkservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
class NetworkService(Resource):
address = attr.ib(validator=attr.validators.instance_of(str))
username = attr.ib(validator=attr.validators.instance_of(str))
password = attr.ib(default='', validator=attr.validators.instance_of(str))
password = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(str)))
port = attr.ib(default=22, validator=attr.validators.instance_of(int))
Loading