[X2Go-Commits] [x2goclient] 51/94: Entirely rewrite PyHocaCLI.authenticate() function. (Fixes: #1308).
git-admin at x2go.org
git-admin at x2go.org
Fri Dec 15 21:06:42 CET 2023
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to annotated tag 0.6.1.0
in repository x2goclient.
commit 34715b3f19c32462696fb202513297f5ace37771
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date: Tue Sep 18 13:10:40 2018 +0200
Entirely rewrite PyHocaCLI.authenticate() function. (Fixes: #1308).
---
debian/changelog | 1 +
pyhoca-cli | 2 +
pyhoca/cli/frontend.py | 177 +++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 151 insertions(+), 29 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 11ecdc90..d0b46a46 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -13,6 +13,7 @@ pyhoca-cli (0.5.99.1-0x2go2) UNRELEASED; urgency=medium
a usable / expectable value.
- Add --forward-sshagent / -A cmdline option for enabling SSH agent
forwarding.
+ - Entirely rewrite PyHocaCLI.authenticate() function. (Fixes: #1308).
* debian/rules:
+ Build for Python3, not Python2.
+ Switch to pybuild DH build system.
diff --git a/pyhoca-cli b/pyhoca-cli
index 1856777d..7bf6138e 100755
--- a/pyhoca-cli
+++ b/pyhoca-cli
@@ -372,6 +372,8 @@ Possible values for the --pack NX option are:
_dummy = int(a.auth_attempts)
except ValueError:
runtime_error ("value for cmd line argument --auth-attempts has to be of type integer", parser=p, exitcode=1)
+ if int(a.auth_attempts) < 1:
+ a.auth_attempts = "1"
if a.server:
diff --git a/pyhoca/cli/frontend.py b/pyhoca/cli/frontend.py
index a73dc2f0..4dbe6439 100644
--- a/pyhoca/cli/frontend.py
+++ b/pyhoca/cli/frontend.py
@@ -468,7 +468,22 @@ class PyHocaCLI(x2go.X2GoClient):
"""
connected = False
- force_password_auth = False
+
+ if self.args.password:
+ password = self.args.password
+ self.args.password = None
+ cmdline_password = True
+ force_password_auth = True
+ else:
+ password = None
+ cmdline_password = False
+ force_password_auth = False
+
+ if self.args.force_password:
+ force_password_auth = True
+
+ passphrase = None
+ passphrase_unlock_counter = 3
_username = self.args.username or self._X2GoClient__get_session_username(self.x2go_session_hash)
@@ -477,53 +492,157 @@ class PyHocaCLI(x2go.X2GoClient):
_username = self.session_profiles.get_broker_username()
try:
- _auth_count = self.auth_attempts +1
+ _auth_count = self.auth_attempts
while not connected and _auth_count:
+
try:
- if self.args.force_password:
- self.args.password = getpass.getpass()
- self._X2GoClient__connect_session(self.x2go_session_hash, username=_username, password=self.args.password, force_password_auth=force_password_auth)
+
+ # decrement authentication counter...
+ _auth_count -= 1
+
+ # show interactive password prompt
+ if force_password_auth and not cmdline_password:
+
+ password = getpass.getpass()
+
+ # workaround for Python bug: http://bugs.python.org/issue11236
+ try:
+ if password is not None and '\x03' in password:
+ raise KeyboardInterrupt()
+ except KeyboardInterrupt:
+ self._runtime_error('Authentication cancelled by user by hitting Ctrl-C at password prompt', exitcode=-200)
+
+ if not password:
+ self._pyhoca_logger('password is empty, please re-try... (hit Ctrl-C plus ENTER to cancel)', loglevel=x2go.loglevel_WARN, )
+ _auth_count += 1
+ continue
+
+ # connection attempt with remote X2Go Server
+ self._X2GoClient__connect_session(self.x2go_session_hash, username=_username, password=password, passphrase=passphrase, force_password_auth=force_password_auth)
+
+ # we succeeeded
connected = True
- force_password_auth = False
+
+ # this will end the loop (as connected is set to True)
+ continue
+
except x2go.PasswordRequiredException as e:
- self._pyhoca_logger('unlock SSH key file (%s)' % self.args.ssh_privkey, loglevel=x2go.loglevel_NOTICE, )
- self.args.password = getpass.getpass()
+
+ # x2go.PasswordRequiredException: This exception gets raised if an SSH pubkey is protected by a passphrase
+
+ if not force_password_auth and passphrase_unlock_counter >= 1:
+ if passphrase == '':
+ self._pyhoca_logger('empty SSH key passphrase (%s), try again...' % self.args.ssh_privkey, loglevel=x2go.loglevel_WARN, )
+ self._pyhoca_logger('unlock SSH key file (%s)' % self.args.ssh_privkey, loglevel=x2go.loglevel_NOTICE, )
+ passphrase = getpass.getpass()
+ passphrase_unlock_counter -= 1
+ # undo auth counter decrement
+ _auth_count += 1
+ continue
+
+ if not force_password_auth and _auth_count >= 1:
+ self._pyhoca_logger('unlocking of SSH key failed, proceeding with interactive login', loglevel=x2go.loglevel_WARN, )
+ force_password_auth = True
+ password = None
+ passphrase = None
+
except x2go.AuthenticationException as e:
- force_password_auth = True
- self._pyhoca_logger('passwordless login for ,,%s\'\' failed' % _username, loglevel=x2go.loglevel_WARN, )
- self._pyhoca_logger('proceeding to interactive login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_NOTICE, )
+
+ # x2go.AuthenticationException: This exception gets raised if the authentication failed
+
+ if force_password_auth:
+ self._pyhoca_logger('password based login for ,,%s\'\' failed [AuthException]' % _username, loglevel=x2go.loglevel_WARN, )
+ else:
+ self._pyhoca_logger('passwordless login for ,,%s\'\' failed [AuthException]' % _username, loglevel=x2go.loglevel_WARN, )
+
+ # if the previous login attempt was pubkey based, enforce interactive login for the next round...
+ if not password and _auth_count >= 1:
+ self._pyhoca_logger('proceeding to interactive login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_NOTICE, )
+ force_password_auth = True
+ # undo auth counter decrement
+ _auth_count += 1
+
+ # a password was provided via the command line
+ elif password and cmdline_password and _auth_count >= 1:
+ self._pyhoca_logger('cmdline provided password failed, proceeding to interactive login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_WARN, )
+ force_password_auth = True
+ cmdline_password = False
+
+ # else, if the previous attempt was already interactive, offer re-trying
+ elif force_password_auth and _auth_count >= 1:
+ self._pyhoca_logger('please re-try login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_NOTICE, )
+
+ passphrase = None
+ password = None
+
except x2go.BadHostKeyException:
+
+ # let's bail out here immediately...
+
self._runtime_error('SSH host key verification for remote host [%s]:%s failed' % (self.args.server, self.args.remote_ssh_port), exitcode=-254)
+
except x2go.SSHException as e:
- if str(e) not in ('not a valid DSA private key file', 'Incompatible ssh peer (no acceptable kex algorithm)', 'No authentication methods available'):
- self._runtime_error(str(e), exitcode=253)
- force_password_auth = True
- self._pyhoca_logger('passwordless login for ,,%s\'\' failed' % _username, loglevel=x2go.loglevel_WARN, )
- self._pyhoca_logger('proceeding to interactive login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_NOTICE, )
- if force_password_auth:
- self.args.password = getpass.getpass()
+ # this bit only captures problems with the SSH key file, other
+ # SSHExceptions are simply ignored (and we proceed to interactive login)
+
+ if str(e).lower().startswith('could not deserialize key data') \
+ :
+
+ # this error gets thrown when the passphrase for unlocking the SSH privkey was wrong
+
+ if not force_password_auth and passphrase_unlock_counter >= 1:
+ if passphrase is not None and passphrase != '':
+ self._pyhoca_logger('wrong SSH key passphrase (%s), try again...' % self.args.ssh_privkey, loglevel=x2go.loglevel_WARN, )
+ self._pyhoca_logger('unlock SSH key file (%s)' % self.args.ssh_privkey, loglevel=x2go.loglevel_NOTICE, )
+ passphrase = getpass.getpass()
+ passphrase_unlock_counter -= 1
+ # undo auth counter decrement
+ _auth_count += 1
+ continue
+
+ if not force_password_auth and _auth_count >= 1:
+ self._pyhoca_logger('unlocking of SSH key failed, proceeding with interactive login', loglevel=x2go.loglevel_WARN, )
+ force_password_auth = True
+ password = None
+ passphrase = None
+
+ elif not str(e).lower().startswith('not a valid dsa private key file') or \
+ not str(e).lower().startswith('not a valid rsa private key file') or \
+ not str(e).lower().startswith('incompatible ssh peer (no acceptable kex algorithm)') or \
+ not str(e).lower().startswith('no authentication methods available') \
+ :
+
+ if force_password_auth:
+ self._pyhoca_logger('password based login for ,,%s\'\' failed [SSHException]' % _username, loglevel=x2go.loglevel_WARN, )
+ else:
+ self._pyhoca_logger('passwordless login for ,,%s\'\' failed [SSHException]' % _username, loglevel=x2go.loglevel_WARN, )
+
+ # let's bail out here...
+ self._runtime_error(str(e), exitcode=253)
- # workaround for Python bug: http://bugs.python.org/issue11236
- try:
- if self.args.password is not None and '\x03' in self.args.password:
- raise KeyboardInterrupt()
- except KeyboardInterrupt:
- self._runtime_error('Authentication cancelled by user by hitting Ctrl-C at password prompt', exitcode=-200)
+ else:
- _auth_count -= 1
+ self._pyhoca_logger('[SSHException] the following error will be ignored: %s' % str(e), loglevel=x2go.loglevel_WARN)
+ self._pyhoca_logger('proceeding to interactive login for user ,,%s\'\'' % _username, loglevel=x2go.loglevel_NOTICE, )
+ force_password_auth = True
+ password = None
+ passphrase = None
- if not connected and not _auth_count:
+ if not connected and _auth_count <= 0:
if self.auth_attempts >= 2:
self._runtime_error('authentication failed, too many failures during interactive login', exitcode=-201)
elif self.auth_attempts == 1:
- self._runtime_error('interactive authentication failed', exitcode=-202)
- else:
- self._runtime_error('non-interactive authentication failed', exitcode=-203)
+ self._runtime_error('authentication failed', exitcode=-202)
+
except socket.error as e:
self._runtime_error('a socket error occured while establishing the connection: %s' % str(e), exitcode=-245)
+ # drop clear text passwords...
+ password = None
+ passphrase = None
+
def MainLoop(self):
"""\
Start the main loop of this application.
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goclient.git
More information about the x2go-commits
mailing list