ipatests: use pexpect to invoke ktutil

`ktutil` is a REPL-style utility that can be controlled only interactively.
The common approach of sending commands to stdin does not work with it on
systems where `readline` library has version less then 8.0 due to a bug
in that version.
With `pexpect` we avoid this bug because it emulates the terminal
when interacting with spawned process instead of simply sending all input
to stdin.

Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Sergey Orlov authored and Alexander Bokovoy committed 2021-02-03 09:06:12 +02:00
1 parent 7363c4b203
commit 1b25270686
1 file changed
+19 -15
+19 -15
View File
@@ -2184,19 +2184,6 @@ class KerberosKeyCopier:
return keys_to_sync
def copy_key(self, keytab, keyentry):
# keyentry.key is a hex value of the actual key
# prefixed with 0x, as produced by klist -K -k.
# However, ktutil accepts hex value without 0x, so
# we should strip first two characters.
stdin = textwrap.dedent("""\
rkt {keytab}
addent -key -p {principal} -k {kvno} -e {etype}
{key}
wkt {keytab}
""").format(keytab=keytab, principal=keyentry.principal,
kvno=keyentry.kvno, etype=keyentry.etype,
key=keyentry.key[2:])
def get_keytab_mtime():
"""Get keytab file mtime.
@@ -2211,8 +2198,25 @@ class KerberosKeyCopier:
mtime_before = get_keytab_mtime()
self.host.run_command([paths.KTUTIL], stdin_text=stdin,
log_stdout=False)
with self.host.spawn_expect(paths.KTUTIL, default_timeout=5) as e:
e.expect_exact('ktutil:')
e.sendline('rkt {}'.format(keytab))
e.expect_exact('ktutil:')
e.sendline(
'addent -key -p {principal} -k {kvno} -e {etype}'
.format(principal=keyentry.principal, kvno=keyentry.kvno,
etype=keyentry.etype,))
e.expect('Key for.+:')
# keyentry.key is a hex value of the actual key
# prefixed with 0x, as produced by klist -K -k.
# However, ktutil accepts hex value without 0x, so
# we should strip first two characters.
e.sendline(keyentry.key[2:])
e.expect_exact('ktutil:')
e.sendline('wkt {}'.format(keytab))
e.expect_exact('ktutil:')
e.sendline('q')
if mtime_before == get_keytab_mtime():
raise Exception('{} did not update keytab file "{}"'.format(
paths.KTUTIL, keytab))