SCAutolib 3.1.2__tar.gz → 3.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {SCAutolib-3.1.2/SCAutolib.egg-info → scautolib-3.3.2}/PKG-INFO +2 -2
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/controller.py +32 -11
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/enums.py +7 -5
- scautolib-3.3.2/SCAutolib/isDistro.py +50 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/CA.py +3 -2
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/file.py +21 -1
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/gui.py +114 -6
- scautolib-3.3.2/SCAutolib/templates/sssd.conf-10 +18 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/utils.py +0 -23
- {SCAutolib-3.1.2 → scautolib-3.3.2/SCAutolib.egg-info}/PKG-INFO +2 -2
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib.egg-info/SOURCES.txt +3 -1
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib.egg-info/requires.txt +1 -1
- {SCAutolib-3.1.2 → scautolib-3.3.2}/requirements.txt +1 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/setup.py +1 -2
- {SCAutolib-3.1.2 → scautolib-3.3.2}/LICENSE +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/MANIFEST.in +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/README.md +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/__init__.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/cli_commands.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/exceptions.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/__init__.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/authselect.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/card.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/log.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/models/user.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/ca.cnf +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/gnome_disable_welcome +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/softhsm2.conf +0 -0
- /SCAutolib-3.1.2/SCAutolib/templates/sssd.conf → /scautolib-3.3.2/SCAutolib/templates/sssd.conf-8or9 +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/user.cnf +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/virt_cacard.service +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib/templates/virtcacard.cil +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib.egg-info/dependency_links.txt +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib.egg-info/entry_points.txt +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/SCAutolib.egg-info/top_level.txt +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/setup.cfg +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_ca.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_card.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_cli.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_controller.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_file.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_openssl_conf.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_sssd_conf.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_user.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/test/test_utils.py +0 -0
- {SCAutolib-3.1.2 → scautolib-3.3.2}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: SCAutolib
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: Python library for automation tests of smart cards using virtualization.
|
|
5
5
|
Home-page: https://github.com/redhat-qe-security/SCAutolib
|
|
6
6
|
Author: Pavel Yadlouski
|
|
@@ -25,8 +25,8 @@ Requires-Dist: pytest>=7
|
|
|
25
25
|
Requires-Dist: schema>=0.7
|
|
26
26
|
Requires-Dist: python_freeipa>=1.0
|
|
27
27
|
Requires-Dist: pexpect>=4
|
|
28
|
+
Requires-Dist: distro>=1.5.0
|
|
28
29
|
Provides-Extra: graphical
|
|
29
|
-
Requires-Dist: python-uinput; extra == "graphical"
|
|
30
30
|
Requires-Dist: opencv-python; extra == "graphical"
|
|
31
31
|
Requires-Dist: pandas; extra == "graphical"
|
|
32
32
|
Requires-Dist: numpy; extra == "graphical"
|
|
@@ -12,10 +12,11 @@ from SCAutolib import (logger, run, LIB_DIR, LIB_BACKUP, LIB_DUMP,
|
|
|
12
12
|
from SCAutolib.models import CA, file, user, card, authselect as auth
|
|
13
13
|
from SCAutolib.models.file import File, OpensslCnf
|
|
14
14
|
from SCAutolib.models.CA import BaseCA
|
|
15
|
-
from SCAutolib.enums import (
|
|
15
|
+
from SCAutolib.enums import (CardType, UserType)
|
|
16
16
|
from SCAutolib.utils import (_check_selinux, _gen_private_key,
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
_install_packages, _check_packages,
|
|
18
|
+
dump_to_json, ca_factory)
|
|
19
|
+
from SCAutolib.isDistro import isDistro
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class Controller:
|
|
@@ -144,7 +145,8 @@ class Controller:
|
|
|
144
145
|
LIB_DUMP_CARDS):
|
|
145
146
|
d.mkdir(exist_ok=True)
|
|
146
147
|
|
|
147
|
-
packages = ["opensc", "httpd", "sssd", "sssd-tools", "gnutls-utils"
|
|
148
|
+
packages = ["opensc", "httpd", "sssd", "sssd-tools", "gnutls-utils",
|
|
149
|
+
"openssl", "nss-tools"]
|
|
148
150
|
if gdm:
|
|
149
151
|
packages.append("gdm")
|
|
150
152
|
|
|
@@ -157,7 +159,11 @@ class Controller:
|
|
|
157
159
|
for c in self.lib_conf["cards"]):
|
|
158
160
|
packages += ["pcsc-lite-ccid", "pcsc-lite", "virt_cacard",
|
|
159
161
|
"vpcd", "softhsm"]
|
|
160
|
-
|
|
162
|
+
extra_args = ""
|
|
163
|
+
if isDistro(['rhel', 'centos'], version='10'):
|
|
164
|
+
# TODO: use better approach later
|
|
165
|
+
extra_args = " centos-stream-10-x86_64"
|
|
166
|
+
run("dnf -y copr enable jjelen/vsmartcard{0}".format(extra_args))
|
|
161
167
|
|
|
162
168
|
# Add IPA packages if needed
|
|
163
169
|
if any([u["user_type"] != UserType.local
|
|
@@ -175,7 +181,14 @@ class Controller:
|
|
|
175
181
|
raise exceptions.SCAutolibException(msg)
|
|
176
182
|
|
|
177
183
|
if graphical:
|
|
178
|
-
|
|
184
|
+
if not isDistro('fedora'):
|
|
185
|
+
run(['dnf', 'groupinstall', 'Server with GUI', '-y',
|
|
186
|
+
'--allowerasing'])
|
|
187
|
+
run(['pip', 'install', 'python-uinput'])
|
|
188
|
+
else:
|
|
189
|
+
# Fedora doesn't have server with GUI group so installed gdm
|
|
190
|
+
# manually and also python3-uinput should be installed from RPM
|
|
191
|
+
run(['dnf', 'install', 'gdm', 'python3-uinput', '-y'])
|
|
179
192
|
# disable subscription message
|
|
180
193
|
run(['systemctl', '--global', 'mask',
|
|
181
194
|
'org.gnome.SettingsDaemon.Subscription.target'])
|
|
@@ -184,8 +197,14 @@ class Controller:
|
|
|
184
197
|
self.dconf_file.save()
|
|
185
198
|
run('dconf update')
|
|
186
199
|
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
if not isDistro('fedora'):
|
|
201
|
+
run(['dnf', 'groupinstall', "Smart Card Support", '-y',
|
|
202
|
+
'--allowerasing'])
|
|
203
|
+
logger.debug("Smart Card Support group in installed.")
|
|
204
|
+
else:
|
|
205
|
+
# Fedora requires rsyslog as well
|
|
206
|
+
run(['dnf', 'install', 'opensc', 'pcsc-lite-ccid', 'rsyslog', '-y'])
|
|
207
|
+
run(['systemctl', 'start', 'rsyslog'])
|
|
189
208
|
|
|
190
209
|
self.sssd_conf.create()
|
|
191
210
|
self.sssd_conf.save()
|
|
@@ -430,6 +449,9 @@ class Controller:
|
|
|
430
449
|
cache_file.unlink()
|
|
431
450
|
logger.debug("Removed opensc file cache")
|
|
432
451
|
|
|
452
|
+
# file only created in graphical mode that is why it is removed.
|
|
453
|
+
self.dconf_file.remove()
|
|
454
|
+
|
|
433
455
|
self.sssd_conf.restore()
|
|
434
456
|
pcscd_service = File("/usr/lib/systemd/system/pcscd.service")
|
|
435
457
|
pcscd_service.restore()
|
|
@@ -514,13 +536,12 @@ class Controller:
|
|
|
514
536
|
|
|
515
537
|
:return: name of the IPA client package for current Linux
|
|
516
538
|
"""
|
|
517
|
-
|
|
518
|
-
if os_version not in (OSVersion.RHEL_9, OSVersion.CentOS_9):
|
|
539
|
+
if isDistro(['rhel', 'centos'], version='8'):
|
|
519
540
|
run("dnf module enable -y idm:DL1")
|
|
520
541
|
run("dnf install @idm:DL1 -y")
|
|
521
542
|
logger.debug("idm:DL1 module is installed")
|
|
522
543
|
|
|
523
|
-
if
|
|
544
|
+
if isDistro('fedora'):
|
|
524
545
|
return ["freeipa-client"]
|
|
525
546
|
else:
|
|
526
547
|
return ["ipa-client"]
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
from enum import Enum, auto
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class OSVersion(Enum):
|
|
4
|
+
class OSVersion(int, Enum):
|
|
5
5
|
"""
|
|
6
6
|
Enumeration for Linux versions. Used for more convenient checks.
|
|
7
7
|
"""
|
|
8
8
|
Fedora = 1
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
RHEL_8 = 2
|
|
10
|
+
RHEL_9 = 3
|
|
11
|
+
RHEL_10 = 4
|
|
12
|
+
CentOS_8 = 5
|
|
13
|
+
CentOS_9 = 6
|
|
14
|
+
CentOS_10 = 7
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class CardType(str, Enum):
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides a function (isDistro) that helps us identify the os
|
|
3
|
+
of the system and configure the system accordingly.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import distro
|
|
7
|
+
from typing import Union
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def isDistro(oses: Union[str, list], version: str = None) -> bool:
|
|
11
|
+
cur_id = distro.id().lower()
|
|
12
|
+
cur_name = distro.name().lower()
|
|
13
|
+
|
|
14
|
+
if isinstance(oses, str):
|
|
15
|
+
results = (oses in cur_id) or (oses in cur_name)
|
|
16
|
+
else:
|
|
17
|
+
results = False
|
|
18
|
+
for item in oses:
|
|
19
|
+
if not isinstance(item, str):
|
|
20
|
+
continue
|
|
21
|
+
item = item.lower()
|
|
22
|
+
results = results or (item in cur_id) or (item in cur_name)
|
|
23
|
+
|
|
24
|
+
if results is False:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
if version:
|
|
28
|
+
cur_major = int(distro.major_version())
|
|
29
|
+
cur_minor = int(distro.minor_version()) if distro.minor_version() else 0
|
|
30
|
+
|
|
31
|
+
if version[0] in ('<', '=', '>'):
|
|
32
|
+
if version[1] == '=':
|
|
33
|
+
op = version[:2]
|
|
34
|
+
version = version[2:]
|
|
35
|
+
else:
|
|
36
|
+
op = version[0] if version[0] != '=' else '=='
|
|
37
|
+
version = version[1:]
|
|
38
|
+
else:
|
|
39
|
+
op = '=='
|
|
40
|
+
|
|
41
|
+
parts = version.split('.')
|
|
42
|
+
major = int(parts[0])
|
|
43
|
+
minor = int(parts[1]) if len(parts) > 1 else None
|
|
44
|
+
|
|
45
|
+
if major == cur_major and minor:
|
|
46
|
+
return eval("{0} {1} {2}".format(cur_minor, op, minor))
|
|
47
|
+
else:
|
|
48
|
+
return eval("{0} {1} {2}".format(cur_major, op, major))
|
|
49
|
+
|
|
50
|
+
return True
|
|
@@ -66,12 +66,13 @@ class BaseCA:
|
|
|
66
66
|
root_cert = f_cert.read()
|
|
67
67
|
|
|
68
68
|
if self._ca_pki_db.exists():
|
|
69
|
+
with self._ca_pki_db.open() as f:
|
|
70
|
+
with self._ca_original_path.open('w') as backup:
|
|
71
|
+
backup.write(f.read())
|
|
69
72
|
# Check if current CA cert is already present in the sssd auth db
|
|
70
73
|
with self._ca_pki_db.open("a+") as f:
|
|
71
74
|
f.seek(0)
|
|
72
75
|
data = f.read()
|
|
73
|
-
with self._ca_original_path.open('w') as backup:
|
|
74
|
-
backup.write(data)
|
|
75
76
|
if root_cert not in data:
|
|
76
77
|
f.write(root_cert)
|
|
77
78
|
else:
|
|
@@ -26,6 +26,7 @@ import json
|
|
|
26
26
|
|
|
27
27
|
from SCAutolib import logger, TEMPLATES_DIR, LIB_BACKUP, LIB_DUMP_CONFS, run
|
|
28
28
|
from SCAutolib.exceptions import SCAutolibException
|
|
29
|
+
from SCAutolib.isDistro import isDistro
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
class File:
|
|
@@ -81,6 +82,16 @@ class File:
|
|
|
81
82
|
with self._template.open() as t:
|
|
82
83
|
self._default_parser.read_file(t)
|
|
83
84
|
|
|
85
|
+
def remove(self):
|
|
86
|
+
"""
|
|
87
|
+
Removes the file if it exists.
|
|
88
|
+
"""
|
|
89
|
+
if self._conf_file.exists():
|
|
90
|
+
self._conf_file.unlink()
|
|
91
|
+
logger.debug(
|
|
92
|
+
f"Removed file {self._conf_file}."
|
|
93
|
+
)
|
|
94
|
+
|
|
84
95
|
def set(self, key: str, value: Union[int, str, bool], section: str = None,
|
|
85
96
|
separator: str = "="):
|
|
86
97
|
"""
|
|
@@ -247,6 +258,10 @@ class File:
|
|
|
247
258
|
logger.debug(
|
|
248
259
|
f"File {self._conf_file} is restored to {original_path}"
|
|
249
260
|
)
|
|
261
|
+
else:
|
|
262
|
+
logger.debug(
|
|
263
|
+
f"File {self._conf_file} was not backed up. Nothing to do."
|
|
264
|
+
)
|
|
250
265
|
|
|
251
266
|
|
|
252
267
|
class SSSDConf(File):
|
|
@@ -263,7 +278,6 @@ class SSSDConf(File):
|
|
|
263
278
|
runtimes.
|
|
264
279
|
"""
|
|
265
280
|
__instance = None
|
|
266
|
-
_template = Path(TEMPLATES_DIR, "sssd.conf")
|
|
267
281
|
_conf_file = Path("/etc/sssd/sssd.conf")
|
|
268
282
|
_backup_original = None
|
|
269
283
|
_backup_default = LIB_BACKUP.joinpath('default-sssd.conf')
|
|
@@ -284,6 +298,12 @@ class SSSDConf(File):
|
|
|
284
298
|
return
|
|
285
299
|
self.__initialized = True
|
|
286
300
|
|
|
301
|
+
if isDistro(['rhel', 'centos'], version='<=9') \
|
|
302
|
+
or isDistro(['fedora'], version='<39'):
|
|
303
|
+
self._template = TEMPLATES_DIR.joinpath("sssd.conf-8or9")
|
|
304
|
+
else:
|
|
305
|
+
self._template = TEMPLATES_DIR.joinpath("sssd.conf-10")
|
|
306
|
+
|
|
287
307
|
# _default_parser object stores default content of config file
|
|
288
308
|
self._default_parser = ConfigParser()
|
|
289
309
|
# avoid problems with inserting some 'specific' values
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import inspect
|
|
1
3
|
import os
|
|
4
|
+
from os.path import join
|
|
2
5
|
from time import sleep, time
|
|
3
6
|
|
|
4
7
|
import cv2
|
|
@@ -6,19 +9,44 @@ import keyboard
|
|
|
6
9
|
import numpy as np
|
|
7
10
|
import pytesseract
|
|
8
11
|
import uinput
|
|
12
|
+
import logging
|
|
9
13
|
|
|
10
14
|
from SCAutolib import run, logger
|
|
15
|
+
from SCAutolib.isDistro import isDistro
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class HTMLFileHandler(logging.FileHandler):
|
|
19
|
+
"""Extending FileHandler to work with HTML files."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self, filename, mode='a', encoding=None, delay=False, errors=None):
|
|
23
|
+
"""
|
|
24
|
+
A handler class which writes formatted logging records to disk HTML
|
|
25
|
+
files.
|
|
26
|
+
"""
|
|
27
|
+
super(HTMLFileHandler, self).__init__(
|
|
28
|
+
filename, mode, encoding, delay, errors
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Do whatever it takes to actually log the specified logging record.
|
|
34
|
+
"""
|
|
35
|
+
custom_record = copy.deepcopy(record)
|
|
36
|
+
custom_record.msg = str(record.msg).rstrip().replace("\n", "<br>\n")
|
|
37
|
+
return super().emit(custom_record)
|
|
11
38
|
|
|
12
39
|
|
|
13
40
|
class Screen:
|
|
14
41
|
"""Captures the screenshots."""
|
|
15
42
|
|
|
16
|
-
def __init__(self, directory: str):
|
|
43
|
+
def __init__(self, directory: str, html_file: str = None):
|
|
17
44
|
"""Init method
|
|
18
45
|
:param directory: Path to directory, where the screenshots
|
|
19
46
|
will be saved.
|
|
20
47
|
"""
|
|
21
48
|
self.directory = directory
|
|
49
|
+
self.html_file = html_file
|
|
22
50
|
self.screenshot_num = 1
|
|
23
51
|
|
|
24
52
|
def screenshot(self, timeout: float = 30):
|
|
@@ -50,13 +78,19 @@ class Screen:
|
|
|
50
78
|
if not captured:
|
|
51
79
|
raise Exception('Could not capture screenshot within timeout.')
|
|
52
80
|
|
|
81
|
+
if self.html_file:
|
|
82
|
+
with open(self.html_file, 'a') as fp:
|
|
83
|
+
fp.write(
|
|
84
|
+
f"<img src=\"screenshots/{self.screenshot_num}.png\" "
|
|
85
|
+
f"alt=\"screenshot number {self.screenshot_num}\">"
|
|
86
|
+
)
|
|
87
|
+
|
|
53
88
|
self.screenshot_num += 1
|
|
54
89
|
return filename
|
|
55
90
|
|
|
56
91
|
|
|
57
92
|
class Mouse:
|
|
58
|
-
"""Controls the mouse of the system under test
|
|
59
|
-
"""
|
|
93
|
+
"""Controls the mouse of the system under test"""
|
|
60
94
|
|
|
61
95
|
def __init__(self):
|
|
62
96
|
run(['modprobe', 'uinput'], check=True)
|
|
@@ -223,18 +257,51 @@ def log_decorator(func):
|
|
|
223
257
|
class GUI:
|
|
224
258
|
"""Represents the GUI and allows controlling the system under test."""
|
|
225
259
|
|
|
226
|
-
def __init__(self, wait_time: float = 5):
|
|
260
|
+
def __init__(self, wait_time: float = 5, res_dir_name: str = None):
|
|
227
261
|
"""Initializes the GUI of system under test.
|
|
228
262
|
|
|
229
263
|
:param wait_time: Time to wait after each action
|
|
264
|
+
:param custom_dir_name: Provide a custom name of the results dir under
|
|
265
|
+
/tmp/SC-tests/. The default is `timestamp`_`caller func's name`.
|
|
230
266
|
"""
|
|
231
267
|
|
|
232
268
|
self.wait_time = wait_time
|
|
233
269
|
self.gdm_init_time = 10
|
|
234
270
|
# Create the directory for screenshots
|
|
235
|
-
|
|
271
|
+
if res_dir_name:
|
|
272
|
+
self.html_directory = '/tmp/SC-tests/' + res_dir_name
|
|
273
|
+
else:
|
|
274
|
+
calling_func = inspect.stack()[1][3]
|
|
275
|
+
self.html_directory = '/tmp/SC-tests/' + str(int(time()))
|
|
276
|
+
self.html_directory += "_" + calling_func
|
|
277
|
+
|
|
278
|
+
self.screenshot_directory = self.html_directory + "/screenshots"
|
|
279
|
+
# will create both dirs
|
|
236
280
|
os.makedirs(self.screenshot_directory, exist_ok=True)
|
|
237
281
|
|
|
282
|
+
self.html_file = join(self.html_directory, "index.html")
|
|
283
|
+
with open(self.html_file, 'w') as fp:
|
|
284
|
+
fp.write(
|
|
285
|
+
"<html lang=\"en\">\n"
|
|
286
|
+
"<head>\n"
|
|
287
|
+
"<meta charset=\"UTF-8\">\n"
|
|
288
|
+
"<meta name=\"viewport\" content=\"width=device-width, "
|
|
289
|
+
"initial-scale=1.0\">\n"
|
|
290
|
+
"<title>Test Results</title>\n"
|
|
291
|
+
"</head>\n"
|
|
292
|
+
"<body style=\"background-color:#000\">\n"
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
fmt = "<span style=\"color:white;\">"
|
|
296
|
+
fmt += "%(name)s:%(module)s.%(funcName)s.%(lineno)d </span>"
|
|
297
|
+
fmt += "<span style=\"color:royalblue;\">[%(levelname)s] </span>"
|
|
298
|
+
fmt += "<span style=\"color:limegreen;\">%(message)s</span>"
|
|
299
|
+
self.fileHandler = HTMLFileHandler(self.html_file)
|
|
300
|
+
self.fileHandler.setLevel(logging.DEBUG)
|
|
301
|
+
self.fileHandler.setFormatter(
|
|
302
|
+
logging.Formatter("<p>" + fmt + "</p>")
|
|
303
|
+
)
|
|
304
|
+
|
|
238
305
|
self.mouse = Mouse()
|
|
239
306
|
|
|
240
307
|
# workaround for keyboard library
|
|
@@ -242,18 +309,29 @@ class GUI:
|
|
|
242
309
|
keyboard.send('enter')
|
|
243
310
|
|
|
244
311
|
def __enter__(self):
|
|
245
|
-
self.screen = Screen(self.screenshot_directory)
|
|
312
|
+
self.screen = Screen(self.screenshot_directory, self.html_file)
|
|
246
313
|
# By restarting gdm, the system gets into defined state
|
|
247
314
|
run(['systemctl', 'restart', 'gdm'], check=True)
|
|
248
315
|
# Cannot screenshot before gdm starts displaying
|
|
249
316
|
# This would break the display
|
|
250
317
|
sleep(self.gdm_init_time)
|
|
251
318
|
|
|
319
|
+
logger.addHandler(self.fileHandler)
|
|
320
|
+
|
|
252
321
|
return self
|
|
253
322
|
|
|
254
323
|
def __exit__(self, type, value, traceback):
|
|
255
324
|
run(['systemctl', 'stop', 'gdm'], check=True)
|
|
256
325
|
|
|
326
|
+
with open(self.html_file, 'a') as fp:
|
|
327
|
+
fp.write(
|
|
328
|
+
"</body>\n"
|
|
329
|
+
"</html>\n"
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
logger.removeHandler(self.fileHandler)
|
|
333
|
+
logger.info(f"HTML file with results created in {self.html_directory}.")
|
|
334
|
+
|
|
257
335
|
@action_decorator
|
|
258
336
|
@log_decorator
|
|
259
337
|
def click_on(self, key: str, timeout: float = 30):
|
|
@@ -385,3 +463,33 @@ class GUI:
|
|
|
385
463
|
if selection.sum() != 0:
|
|
386
464
|
raise Exception(f"The key='{key}' was found "
|
|
387
465
|
f"in the screenshot {screenshot}")
|
|
466
|
+
|
|
467
|
+
@log_decorator
|
|
468
|
+
def check_home_screen(self, polarity: bool = True):
|
|
469
|
+
"""
|
|
470
|
+
Check for the home screen to determine if user is logged in
|
|
471
|
+
|
|
472
|
+
If OS version is defined as Fedora, we set the text for which to
|
|
473
|
+
search to "tosearch" instead of the original "Activities". In later
|
|
474
|
+
versions of Fedora, "Activities" text is no longer visible. "tosearch"
|
|
475
|
+
should be visible on the login screen as the search bar is still
|
|
476
|
+
present.
|
|
477
|
+
|
|
478
|
+
After defining polarity and the string to check, run the appropriate
|
|
479
|
+
function with the string to search for.
|
|
480
|
+
|
|
481
|
+
:param polarity: Define whether to search for presence or absence of
|
|
482
|
+
string indicating home screen is displayed.
|
|
483
|
+
"""
|
|
484
|
+
if polarity is True:
|
|
485
|
+
func_str = 'assert_text'
|
|
486
|
+
else:
|
|
487
|
+
func_str = 'assert_no_text'
|
|
488
|
+
|
|
489
|
+
if isDistro('fedora'):
|
|
490
|
+
check_str = 'tosearch'
|
|
491
|
+
else:
|
|
492
|
+
check_str = 'Activities'
|
|
493
|
+
|
|
494
|
+
func = getattr(self, func_str)
|
|
495
|
+
func(check_str, timeout=20)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[sssd]
|
|
2
|
+
debug_level = 9
|
|
3
|
+
services = nss, pam, ssh, sudo
|
|
4
|
+
domains = shadowutils
|
|
5
|
+
certificate_verification = no_ocsp
|
|
6
|
+
|
|
7
|
+
[nss]
|
|
8
|
+
debug_level = 9
|
|
9
|
+
|
|
10
|
+
[pam]
|
|
11
|
+
debug_level = 9
|
|
12
|
+
pam_cert_auth = True
|
|
13
|
+
|
|
14
|
+
[domain/shadowutils]
|
|
15
|
+
debug_level = 9
|
|
16
|
+
id_provider = proxy
|
|
17
|
+
proxy_lib_name = files
|
|
18
|
+
local_auth_policy = only
|
|
@@ -10,7 +10,6 @@ from pathlib import Path
|
|
|
10
10
|
|
|
11
11
|
from SCAutolib import (run, logger, TEMPLATES_DIR, LIB_DUMP_USERS, LIB_DUMP_CAS,
|
|
12
12
|
LIB_DUMP_CARDS)
|
|
13
|
-
from SCAutolib.enums import OSVersion
|
|
14
13
|
from SCAutolib.exceptions import SCAutolibException
|
|
15
14
|
from SCAutolib.models.CA import LocalCA, BaseCA, CustomCA, IPAServerCA
|
|
16
15
|
from SCAutolib.models.card import Card
|
|
@@ -58,28 +57,6 @@ def _gen_private_key(key_path: Path):
|
|
|
58
57
|
encryption_algorithm=serialization.NoEncryption()))
|
|
59
58
|
|
|
60
59
|
|
|
61
|
-
def _get_os_version():
|
|
62
|
-
"""
|
|
63
|
-
Find Linux version. Available version: RHEL 8, RHEL 9, Fedora.
|
|
64
|
-
:return: Enum with OS version
|
|
65
|
-
"""
|
|
66
|
-
with open('/etc/redhat-release', "r") as f:
|
|
67
|
-
cnt = f.read()
|
|
68
|
-
|
|
69
|
-
if "Red Hat Enterprise Linux release 9" in cnt:
|
|
70
|
-
return OSVersion.RHEL_9
|
|
71
|
-
elif "Red Hat Enterprise Linux release 8" in cnt:
|
|
72
|
-
return OSVersion.RHEL_8
|
|
73
|
-
elif "Fedora" in cnt:
|
|
74
|
-
return OSVersion.Fedora
|
|
75
|
-
elif "CentOS Stream release 8" in cnt:
|
|
76
|
-
return OSVersion.CentOS_8
|
|
77
|
-
elif "CentOS Stream release 9" in cnt:
|
|
78
|
-
return OSVersion.CentOS_9
|
|
79
|
-
else:
|
|
80
|
-
raise SCAutolibException("OS is not detected.")
|
|
81
|
-
|
|
82
|
-
|
|
83
60
|
def _install_packages(packages):
|
|
84
61
|
"""
|
|
85
62
|
Install given packages and log package version
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: SCAutolib
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: Python library for automation tests of smart cards using virtualization.
|
|
5
5
|
Home-page: https://github.com/redhat-qe-security/SCAutolib
|
|
6
6
|
Author: Pavel Yadlouski
|
|
@@ -25,8 +25,8 @@ Requires-Dist: pytest>=7
|
|
|
25
25
|
Requires-Dist: schema>=0.7
|
|
26
26
|
Requires-Dist: python_freeipa>=1.0
|
|
27
27
|
Requires-Dist: pexpect>=4
|
|
28
|
+
Requires-Dist: distro>=1.5.0
|
|
28
29
|
Provides-Extra: graphical
|
|
29
|
-
Requires-Dist: python-uinput; extra == "graphical"
|
|
30
30
|
Requires-Dist: opencv-python; extra == "graphical"
|
|
31
31
|
Requires-Dist: pandas; extra == "graphical"
|
|
32
32
|
Requires-Dist: numpy; extra == "graphical"
|
|
@@ -9,6 +9,7 @@ SCAutolib/cli_commands.py
|
|
|
9
9
|
SCAutolib/controller.py
|
|
10
10
|
SCAutolib/enums.py
|
|
11
11
|
SCAutolib/exceptions.py
|
|
12
|
+
SCAutolib/isDistro.py
|
|
12
13
|
SCAutolib/utils.py
|
|
13
14
|
SCAutolib.egg-info/PKG-INFO
|
|
14
15
|
SCAutolib.egg-info/SOURCES.txt
|
|
@@ -27,7 +28,8 @@ SCAutolib/models/user.py
|
|
|
27
28
|
SCAutolib/templates/ca.cnf
|
|
28
29
|
SCAutolib/templates/gnome_disable_welcome
|
|
29
30
|
SCAutolib/templates/softhsm2.conf
|
|
30
|
-
SCAutolib/templates/sssd.conf
|
|
31
|
+
SCAutolib/templates/sssd.conf-10
|
|
32
|
+
SCAutolib/templates/sssd.conf-8or9
|
|
31
33
|
SCAutolib/templates/user.cnf
|
|
32
34
|
SCAutolib/templates/virt_cacard.service
|
|
33
35
|
SCAutolib/templates/virtcacard.cil
|
|
@@ -15,7 +15,6 @@ with readme.open() as f:
|
|
|
15
15
|
long_description = f.read()
|
|
16
16
|
|
|
17
17
|
graphical_reqs = [
|
|
18
|
-
'python-uinput',
|
|
19
18
|
'opencv-python',
|
|
20
19
|
'pandas',
|
|
21
20
|
'numpy',
|
|
@@ -25,7 +24,7 @@ graphical_reqs = [
|
|
|
25
24
|
|
|
26
25
|
setup(
|
|
27
26
|
name="SCAutolib",
|
|
28
|
-
version="3.
|
|
27
|
+
version="3.3.2",
|
|
29
28
|
description=description,
|
|
30
29
|
long_description=long_description,
|
|
31
30
|
long_description_content_type='text/markdown',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/SCAutolib-3.1.2/SCAutolib/templates/sssd.conf → /scautolib-3.3.2/SCAutolib/templates/sssd.conf-8or9
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|