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_pass
|
||||||
- name: ansible_ssh_password
|
- name: ansible_ssh_password
|
||||||
sshpass_prompt:
|
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: ''
|
default: ''
|
||||||
ini:
|
ini:
|
||||||
- section: 'ssh_connection'
|
- section: 'ssh_connection'
|
||||||
|
@ -322,6 +324,17 @@ DOCUMENTATION = '''
|
||||||
cli:
|
cli:
|
||||||
- name: timeout
|
- name: timeout
|
||||||
type: integer
|
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
|
import errno
|
||||||
|
@ -622,15 +635,21 @@ class Connection(ConnectionBase):
|
||||||
|
|
||||||
# If we want to use password authentication, we have to set up a pipe to
|
# If we want to use password authentication, we have to set up a pipe to
|
||||||
# write the password to sshpass.
|
# write the password to sshpass.
|
||||||
|
pkcs11_provider = self.get_option("pkcs11_provider")
|
||||||
if conn_password:
|
if conn_password or pkcs11_provider:
|
||||||
if not self._sshpass_available():
|
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()
|
self.sshpass_pipe = os.pipe()
|
||||||
b_command += [b'sshpass', b'-d' + to_bytes(self.sshpass_pipe[0], nonstring='simplerepr', errors='surrogate_or_strict')]
|
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')
|
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:
|
if password_prompt:
|
||||||
b_command += [b'-P', to_bytes(password_prompt, errors='surrogate_or_strict')]
|
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.
|
# 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
|
# sftp batch mode allows us to correctly catch failed transfers, but can
|
||||||
# be disabled if the client side doesn't support the option. However,
|
# 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
|
# sftp batch mode does not prompt for passwords so it must be disabled
|
||||||
|
|
|
@ -80,6 +80,8 @@ class TestConnectionBaseClass(unittest.TestCase):
|
||||||
pc = PlayContext()
|
pc = PlayContext()
|
||||||
new_stdin = StringIO()
|
new_stdin = StringIO()
|
||||||
conn = connection_loader.get('ssh', pc, new_stdin)
|
conn = connection_loader.get('ssh', pc, new_stdin)
|
||||||
|
conn.get_option = MagicMock()
|
||||||
|
conn.get_option.return_value = ""
|
||||||
conn._build_command('ssh', 'ssh')
|
conn._build_command('ssh', 'ssh')
|
||||||
|
|
||||||
def test_plugins_connection_ssh_exec_command(self):
|
def test_plugins_connection_ssh_exec_command(self):
|
||||||
|
|
Loading…
Reference in a new issue