Hello community, here is the log from the commit of package cobbler for openSUSE:Factory checked in at 2020-09-29 19:05:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cobbler (Old) and /work/SRC/openSUSE:Factory/.cobbler.new.4249 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cobbler" Tue Sep 29 19:05:49 2020 rev:58 rq:838538 version:3.1.2 Changes: -------- --- /work/SRC/openSUSE:Factory/cobbler/cobbler.changes 2020-09-07 21:37:19.709435587 +0200 +++ /work/SRC/openSUSE:Factory/.cobbler.new.4249/cobbler.changes 2020-09-29 19:05:54.894060586 +0200 @@ -1,0 +2,27 @@ +Tue Sep 22 09:39:25 UTC 2020 - Dominik Gedon <dominik.ge...@suse.com> + +- Add fence-agents package as requirement +- Fix position of wrong endif + +------------------------------------------------------------------- +Tue Sep 15 13:42:00 UTC 2020 - Alexander Graul <alexander.gr...@suse.com> + +- Add cobbler-tests subpackage for unit testing for openSUSE/SLE + +------------------------------------------------------------------- +Fri Sep 11 15:00:02 UTC 2020 - Jochen Breuer <jbre...@suse.de> + +- Adds LoadModule definitions for openSUSE/SLE + +- Added: + * load_module_apache_suse_fix.diff + +------------------------------------------------------------------- +Wed Sep 9 07:16:51 UTC 2020 - Dominik Gedon <dominik.ge...@suse.com> + +- Switch to new refactored auth module. + +- Added: + * refactored_auth_module.diff + +------------------------------------------------------------------- New: ---- load_module_apache_suse_fix.diff refactored_auth_module.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cobbler.spec ++++++ --- /var/tmp/diff_new_pack.lsYxx0/_old 2020-09-29 19:05:55.790061491 +0200 +++ /var/tmp/diff_new_pack.lsYxx0/_new 2020-09-29 19:05:55.790061491 +0200 @@ -28,7 +28,7 @@ %define apache_user wwwrun %define apache_group www %define apache_log /var/log/apache2 -%define apache_webconfigdir /etc/apache2/vhosts.d +%define apache_webconfigdir /etc/apache2/conf.d %define apache_mod_wsgi apache2-mod_wsgi-python%{python3_pkgversion} %define tftpboot_dir /srv/tftpboot %define tftpsrv_pkg tftp @@ -132,6 +132,8 @@ Source1: cobbler.rpmlintrc BuildArch: noarch Patch0: cgi_parse_qs_is_deprecated.diff +Patch1: refactored_auth_module.diff +Patch2: load_module_apache_suse_fix.diff BuildRequires: git-core BuildRequires: %{system_release_pkg} @@ -182,6 +184,7 @@ Requires: %{apache_pkg} Requires: %{tftpsrv_pkg} Requires: %{createrepo_pkg} +Requires: fence-agents Requires: rsync Requires: xorriso %{?python_enable_dependency_generator} @@ -250,10 +253,22 @@ Web interface for Cobbler that allows visiting http://server/cobbler_web to configure the install server. +%if 0%{?suse_version} +%package tests +Summary: Unit tests for cobbler +Requires: cobbler = %{version}-%{release} + +%description tests +Unit test files from the Cobbler project +%endif %prep %setup %patch0 -p1 +%patch1 -p1 +%if 0%{?suse_version} +%patch2 -p1 +%endif %if 0%{?suse_version} # Set tftpboot location correctly for SUSE distributions @@ -273,6 +288,11 @@ mkdir -p %{buildroot}%{_sysconfdir}/logrotate.d mv %{buildroot}%{_sysconfdir}/cobbler/cobblerd_rotate %{buildroot}%{_sysconfdir}/logrotate.d/cobblerd +# No VirtualHost definition as it overwrite all the Uyuni RewriteRules configured in conf.d/ +mkdir -p %{buildroot}%{_sysconfdir}/apache2/conf.d +mv %{buildroot}%{_sysconfdir}/apache2/vhosts.d/cobbler.conf %{buildroot}%{_sysconfdir}/apache2/conf.d +sed -i 's/^.*VirtualHost.*$//g' %{buildroot}%{_sysconfdir}/apache2/conf.d/cobbler.conf + # Create data directories in tftpboot_dir mkdir -p %{buildroot}%{tftpboot_dir}/{boot,etc,grub,images{,2},ppc,pxelinux.cfg,s390x} @@ -286,6 +306,11 @@ # cobbler-web rm %{buildroot}%{_sysconfdir}/cobbler/cobbler_web.conf +%if 0%{?suse_version} +# cobbler-tests +cp -r tests/ %{buildroot}/%{_datadir}/cobbler/ +%endif + %pre %if %{_vendor} == "debbuild" @@ -454,7 +479,7 @@ %files web %license COPYING %doc AUTHORS.in README.md -%config(noreplace) %{apache_webconfigdir}/cobbler_web.conf +%config(noreplace) %{apache_etc}/vhosts.d/cobbler_web.conf %if %{_vendor} == "debbuild" # Work around broken attr support # Cf. https://github.com/debbuild/debbuild/issues/160 @@ -467,5 +492,10 @@ %attr(-,%{apache_user},%{apache_group}) %{apache_dir}/cobbler_webui_content/ %endif +%if 0%{?suse_version} +%files tests +%dir /usr/share/cobbler/tests +/usr/share/cobbler/tests/* +%endif %changelog ++++++ load_module_apache_suse_fix.diff ++++++ diff --git a/config/apache/cobbler.conf b/config/apache/cobbler.conf index e6f7afef..54ddad0a 100644 --- a/config/apache/cobbler.conf +++ b/config/apache/cobbler.conf @@ -1,6 +1,10 @@ # This configuration file allows cobbler data # to be accessed over HTTP. +LoadModule wsgi_module /usr/lib64/apache2/mod_wsgi.so +LoadModule proxy_module /usr/lib64/apache2/mod_proxy.so +LoadModule proxy_http_module /usr/lib64/apache2/mod_proxy_http.so + AliasMatch ^/cblr(?!/svc/)(.*)?$ "@@webroot@@/cobbler$1" AliasMatch ^/cobbler_track(.*)?$ "@@webroot@@/cobbler$1" #AliasMatch ^/cobbler(.*)?$ "@@webroot@@/cobbler$1" ++++++ refactored_auth_module.diff ++++++ diff --git a/cobbler/modules/authentication/spacewalk.py b/cobbler/modules/authentication/spacewalk.py index c553c8e6f..2bd1c918b 100644 --- a/cobbler/modules/authentication/spacewalk.py +++ b/cobbler/modules/authentication/spacewalk.py @@ -21,10 +21,14 @@ 02110-1301 USA """ - from future import standard_library + standard_library.install_aliases() -import xmlrpc.client + +from cobbler.cexceptions import CX +from cobbler.utils import log_exc +from cobbler import clogger +from xmlrpc.client import ServerProxy, Error def register(): @@ -40,32 +44,66 @@ def __looks_like_a_token(password): /likely/ a token, and we should try to treat it as a token first, if not, we should treat it as a password. All of this code is there to avoid extra XMLRPC calls, which are slow. + A password gets detected as a token if it is lowercase and under 45 characters. + :param password: The password which is possibly a token. :return: True if it is possibly a token or False otherwise. :rtype: bool """ - if password.lower() != password: - # Tokens are always lowercase, this isn't a token. + return password.lower() == password and len(password) > 45 + + +def __check_auth_token(xmlrpc_client, api_handle, username, password): + """ + This checks if the auth token is valid. + :param xmlrpc_client: The xmlrpc client to check access for. + :param api_handle: The api instance to retrieve settings of. + :param username: The username to try. + :param password: The password to try. + :return: In any error case this will return 0. Otherwise the return value of the API which should be 1. + """ + # If the token is not a token this will raise an exception rather than return an integer. + try: + return xmlrpc_client.auth.checkAuthToken(username, password) + except Error: + logger = api_handle.logger + logger.error("Error while checking authentication token.") + log_exc(logger) return False - # We can't use binascii.unhexlify here as it's an "odd length string". - # try: - # #data = binascii.unhexlify(password) - # return True # looks like a token, but we can't be sure - # except: - # return False # definitely not a token - return (len(password) > 45) +def __check_user_login(xmlrpc_client, api_handle, user_enabled, username, password): + """ + This actually performs the login to spacewalk. + + :param xmlrpc_client: The xmlrpc client bound to the target spacewalk instance. + :param api_handle: The api instance to retrieve settings of. + :param user_enabled: Weather we allow Spacewalk users to log in or not. + :type user_enabled: bool + :param username: The username to log in. + :param password: The password to log in. + :return: True if users are allowed to log in and he is of the role ``config_admin`` or ``org_admin``. + """ + try: + session = xmlrpc_client.auth.login(username, password) + # login success by username, role must also match and user_enabled needs to be true. + roles = xmlrpc_client.user.listRoles(session, username) + if user_enabled and ("config_admin" in roles or "org_admin" in roles): + return True + except Error: + logger = api_handle.logger + logger.error("Error while checking user authentication data.") + log_exc(logger) + return False def authenticate(api_handle, username, password): """ - Validate a username/password combo, returning True/False - - This will pass the username and password back to Spacewalk to see if this authentication request is valid. + Validate a username/password combo. This will pass the username and password back to Spacewalk to see if this + authentication request is valid. - See also: https://github.com/uyuni-project/uyuni/blob/bbbbbf537a1928c1922015c70322034a89b1cb9a/java/code/src/com/redhat/rhn/frontend/xmlrpc/auth/AuthHandler.java#L133 + See also: https://github.com/uyuni-project/uyuni/blob/master/java/code/src/com/redhat/rhn/frontend/xmlrpc/auth/AuthHandler.java#L133 :param api_handle: The api instance to retrieve settings of. :param username: The username to authenticate agains spacewalk/uyuni/SUSE Manager @@ -74,78 +112,25 @@ def authenticate(api_handle, username, password): :rtype: bool """ - if api_handle is not None: - server = api_handle.settings().redhat_management_server - user_enabled = api_handle.settings().redhat_management_permissive - else: - server = "columbia.devel.redhat.com" - user_enabled = True - - if server == "xmlrpc.rhn.redhat.com": - # Emergency fail, don't bother RHN! - return False + if api_handle is None: + raise CX("api_handle required. Please don't call this without it.") + server = api_handle.settings().redhat_management_server + user_enabled = api_handle.settings().redhat_management_permissive spacewalk_url = "https://%s/rpc/api" % server - client = xmlrpc.client.Server(spacewalk_url, verbose=0) - - if __looks_like_a_token(password) or username == 'taskomatic_user': - # The tokens are lowercase hex, but a password can also be lowercase hex, so we have to try it as both a token - # and then a password if we are unsure. We do it this way to be faster but also to avoid any login failed stuff - # in the logs that we don't need to send. - - try: - valid = client.auth.checkAuthToken(username, password) - except: - # If the token is not a token this will raise an exception rather than return an integer. - valid = 0 - - # Problem at this point, 0xdeadbeef is valid as a token but if that fails, it's also a valid password, so we - # must try auth system #2 - - if valid != 1: - # First API code returns 1 on success the second uses exceptions for login failed. - # So... token check failed, but maybe the username/password is just a simple username/pass! - - if user_enabled == 0: - # this feature must be explicitly enabled. - return False - - session = "" - try: - session = client.auth.login(username, password) - except: - # FIXME: Should log exceptions that are not excepted as we could detect spacewalk java errors here that - # are not login related. - return False - - # login success by username, role must also match - roles = client.user.listRoles(session, username) - if not ("config_admin" in roles or "org_admin" in roles): - return False - - return True - - else: - # It's an older version of spacewalk, so just try the username/pass. - # OR: We know for sure it's not a token because it's not lowercase hex. - - if user_enabled == 0: - # this feature must be explicitly enabled. - return False - - session = "" - try: - session = client.auth.login(username, password) - except: - return False - - # login success by username, role must also match - roles = client.user.listRoles(session, username) - if not ("config_admin" in roles or "org_admin" in roles): - return False - - return True - - -if __name__ == "__main__": - print((authenticate(None, "admin", "redhat"))) + with ServerProxy(spacewalk_url, verbose=True) as client: + if username == 'taskomatic_user' or __looks_like_a_token(password): + # The tokens are lowercase hex, but a password can also be lowercase hex, so we have to try it as both a + # token and then a password if we are unsure. We do it this way to be faster but also to avoid any login + # failed stuff in the logs that we don't need to send. + + # Problem at this point, 0xdeadbeef is valid as a token but if that fails, it's also a valid password, so we + # must try auth system #2 + + if __check_auth_token(client, api_handle, username, password) != 1: + return __check_user_login(client, api_handle, user_enabled, username, password) + return True + else: + # It's an older version of spacewalk, so just try the username/pass. + # OR: We know for sure it's not a token because it's not lowercase hex. + return __check_user_login(client, api_handle, user_enabled, username, password)