add pkcs11 support to Ansible ssh connection module (#32829)
* rebased with upstream * removed extra usetty as it wasnt needed, style changes, added var option setable by inventory for pkcs11 * update pkcs11_provider version_added * Update lib/ansible/plugins/connection/ssh.py Co-authored-by: Jordan Borean <jborean93@gmail.com> * Update lib/ansible/plugins/connection/ssh.py Correct logic for a password being required for pkcs11_provider Co-authored-by: Jordan Borean <jborean93@gmail.com> * style nit fixes for checking pkcs11_provider is set * fixed duplication when using password_prompt with pkcs11_provider * added changelog fragment * added changelog fragment Co-authored-by: David Whiteside <david.whiteside@nrel.gov> Co-authored-by: Matt Davis <nitzmahone@users.noreply.github.com> Co-authored-by: Jordan Borean <jborean93@gmail.com>
This commit is contained in:
parent
d9183b8df5
commit
805799ac8b
3 changed files with 37 additions and 4 deletions
|
@ -0,0 +1,3 @@
|
|||
minor_changes:
|
||||
- ssh - added pkcs11 support by adding the pkcs11_provider option in the
|
||||
ssh connection module. (https://www.github.com/ansible/ansible/pull/32829)
|
|
@ -56,7 +56,9 @@ DOCUMENTATION = '''
|
|||
- name: ansible_ssh_pass
|
||||
- name: ansible_ssh_password
|
||||
sshpass_prompt:
|
||||
description: Password prompt that sshpass should search for. Supported by sshpass 1.06 and up.
|
||||
description:
|
||||
- Password prompt that sshpass should search for. Supported by sshpass 1.06 and up.
|
||||
- Defaults to ``Enter PIN for`` when pkcs11_provider is set.
|
||||
default: ''
|
||||
ini:
|
||||
- section: 'ssh_connection'
|
||||
|
@ -322,6 +324,17 @@ DOCUMENTATION = '''
|
|||
cli:
|
||||
- name: timeout
|
||||
type: integer
|
||||
pkcs11_provider:
|
||||
version_added: '2.12'
|
||||
default: ""
|
||||
description:
|
||||
- "PKCS11 SmartCard provider such as opensc, example: /usr/local/lib/opensc-pkcs11.so"
|
||||
- Requires sshpass version 1.06+, sshpass must support the -P option
|
||||
env: [{name: ANSIBLE_PKCS11_PROVIDER}]
|
||||
ini:
|
||||
- {key: pkcs11_provider, section: ssh_connection}
|
||||
vars:
|
||||
- name: ansible_ssh_pkcs11_provider
|
||||
'''
|
||||
|
||||
import errno
|
||||
|
@ -622,15 +635,21 @@ class Connection(ConnectionBase):
|
|||
|
||||
# If we want to use password authentication, we have to set up a pipe to
|
||||
# write the password to sshpass.
|
||||
|
||||
if conn_password:
|
||||
pkcs11_provider = self.get_option("pkcs11_provider")
|
||||
if conn_password or pkcs11_provider:
|
||||
if not self._sshpass_available():
|
||||
raise AnsibleError("to use the 'ssh' connection type with passwords, you must install the sshpass program")
|
||||
raise AnsibleError("to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program")
|
||||
if not conn_password and pkcs11_provider:
|
||||
raise AnsibleError("to use pkcs11_provider you must specify a password/pin")
|
||||
|
||||
self.sshpass_pipe = os.pipe()
|
||||
b_command += [b'sshpass', b'-d' + to_bytes(self.sshpass_pipe[0], nonstring='simplerepr', errors='surrogate_or_strict')]
|
||||
|
||||
password_prompt = self.get_option('sshpass_prompt')
|
||||
if not password_prompt and pkcs11_provider:
|
||||
# Set default password prompt for pkcs11_provider to make it clear its a PIN
|
||||
password_prompt = 'Enter PIN for '
|
||||
|
||||
if password_prompt:
|
||||
b_command += [b'-P', to_bytes(password_prompt, errors='surrogate_or_strict')]
|
||||
|
||||
|
@ -640,6 +659,15 @@ class Connection(ConnectionBase):
|
|||
# Next, additional arguments based on the configuration.
|
||||
#
|
||||
|
||||
# pkcs11 mode allows the use of Smartcards or Yubikey devices
|
||||
if conn_password and pkcs11_provider:
|
||||
self._add_args(b_command,
|
||||
(b"-o", b"KbdInteractiveAuthentication=no",
|
||||
b"-o", b"PreferredAuthentications=publickey",
|
||||
b"-o", b"PasswordAuthentication=no",
|
||||
b'-o', to_bytes(u'PKCS11Provider=%s' % pkcs11_provider)),
|
||||
u'Enable pkcs11')
|
||||
|
||||
# sftp batch mode allows us to correctly catch failed transfers, but can
|
||||
# be disabled if the client side doesn't support the option. However,
|
||||
# sftp batch mode does not prompt for passwords so it must be disabled
|
||||
|
|
|
@ -80,6 +80,8 @@ class TestConnectionBaseClass(unittest.TestCase):
|
|||
pc = PlayContext()
|
||||
new_stdin = StringIO()
|
||||
conn = connection_loader.get('ssh', pc, new_stdin)
|
||||
conn.get_option = MagicMock()
|
||||
conn.get_option.return_value = ""
|
||||
conn._build_command('ssh', 'ssh')
|
||||
|
||||
def test_plugins_connection_ssh_exec_command(self):
|
||||
|
|
Loading…
Reference in a new issue