diff --git a/plogical/applicationInstaller.py b/plogical/applicationInstaller.py index 16ee18cf2..d4f777678 100755 --- a/plogical/applicationInstaller.py +++ b/plogical/applicationInstaller.py @@ -1784,9 +1784,9 @@ def wordpressInstallNew(self): DataToPass['websiteOwner'] = self.data['websiteOwner'] DataToPass['package'] = self.data['package'] DataToPass['ssl'] = 1 - DataToPass['dkimCheck'] = 0 + DataToPass['dkimCheck'] = 1 DataToPass['openBasedir'] = 0 - DataToPass['mailDomain'] = 0 + DataToPass['mailDomain'] = 1 DataToPass['apacheBackend'] = self.extraArgs['apacheBackend'] UserID = self.data['adminID'] diff --git a/plogical/sslUtilities.py b/plogical/sslUtilities.py index 38b30a4d1..945274a8d 100755 --- a/plogical/sslUtilities.py +++ b/plogical/sslUtilities.py @@ -18,6 +18,54 @@ class sslUtilities: Server_root = "/usr/local/lsws" redisConf = '/usr/local/lsws/conf/dvhost_redis.conf' + DONT_ISSUE = 0 + ISSUE_SELFSIGNED = 1 + ISSUE_SSL = 2 + + @staticmethod + def getDomainsCovered(cert_path): + try: + from cryptography import x509 + from cryptography.hazmat.backends import default_backend + with open(cert_path, 'rb') as cert_file: + cert_data = cert_file.read() + cert = x509.load_pem_x509_certificate(cert_data, default_backend()) + + # Check for the Subject Alternative Name (SAN) extension + san_extension = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) + + if san_extension: + # Extract and print the domains from SAN + san_domains = san_extension.value.get_values_for_type(x509.DNSName) + return 1, san_domains + else: + # If SAN is not present, return the Common Name as a fallback + return 0, None + except BaseException as msg: + return 0, str(msg) + + + @staticmethod + def CheckIfSSLNeedsToBeIssued(virtualHostName): + #### if website already have an SSL, better not issue again - need to check for wild-card + filePath = '/etc/letsencrypt/live/%s/fullchain.pem' % (virtualHostName) + if os.path.exists(filePath): + import OpenSSL + x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(filePath, 'r').read()) + SSLProvider = x509.get_issuer().get_components()[1][1].decode('utf-8') + + if SSLProvider != 'Denial': + return sslUtilities.ISSUE_SSL + else: + status, domains = sslUtilities.getDomainsCovered(filePath) + + if status: + if len(domains) > 1: + return sslUtilities.DONT_ISSUE + else: + return sslUtilities.ISSUE_SSL + + @staticmethod def checkIfSSLMap(virtualHostName): try: @@ -406,15 +454,10 @@ def obtainSSLForADomain(virtualHostName, adminEmail, sslpath, aliasDomain=None): if retStatus == 1: return retStatus - #### if website already have an SSL, better not issue again - need to check for wild-card - filePath = '/etc/letsencrypt/live/%s/fullchain.pem' % (virtualHostName) - if os.path.exists(filePath): - import OpenSSL - x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(filePath, 'r').read()) - SSLProvider = x509.get_issuer().get_components()[1][1].decode('utf-8') - - if SSLProvider != 'Denial': - return 1 + if sslUtilities.CheckIfSSLNeedsToBeIssued(virtualHostName) == sslUtilities.ISSUE_SSL: + pass + else: + return 1 sender_email = 'root@%s' % (socket.gethostname()) @@ -584,6 +627,19 @@ def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain=None): pathToStoreSSLPrivKey = "/etc/letsencrypt/live/%s/privkey.pem" % (domain) pathToStoreSSLFullChain = "/etc/letsencrypt/live/%s/fullchain.pem" % (domain) + #### if in any case ssl failed to obtain and CyberPanel try to issue self-signed ssl, first check if ssl already present. + ### if so, dont issue self-signed ssl, as it may override some existing ssl + + if os.path.exists(pathToStoreSSLFullChain): + import OpenSSL + x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(pathToStoreSSLFullChain, 'r').read()) + SSLProvider = x509.get_issuer().get_components()[1][1].decode('utf-8') + + if SSLProvider != 'Denial': + if sslUtilities.installSSLForDomain(domain) == 1: + logging.CyberCPLogFileWriter.writeToFile("We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www).") + return [1, "We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www)." + " [issueSSLForDomain]"] + command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=' + domain + '" -keyout ' + pathToStoreSSLPrivKey + ' -out ' + pathToStoreSSLFullChain cmd = shlex.split(command) subprocess.call(cmd) diff --git a/plogical/test.py b/plogical/test.py index 743055101..ad96cf00e 100644 --- a/plogical/test.py +++ b/plogical/test.py @@ -38,3 +38,30 @@ # # # Logout # mail.logout() + +from cryptography import x509 +from cryptography.hazmat.backends import default_backend + +def get_domains_covered(cert_path): + with open(cert_path, 'rb') as cert_file: + cert_data = cert_file.read() + cert = x509.load_pem_x509_certificate(cert_data, default_backend()) + + # Check for the Subject Alternative Name (SAN) extension + san_extension = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) + + if san_extension: + # Extract and print the domains from SAN + san_domains = san_extension.value.get_values_for_type(x509.DNSName) + return san_domains + else: + # If SAN is not present, return the Common Name as a fallback + return [cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0].value] + +# Example usage +cert_path = '/etc/letsencrypt/live/cyberplanner.io/fullchain.pem' +domains_covered = get_domains_covered(cert_path) + +print("Domains covered by the certificate:") +for domain in domains_covered: + print(domain) diff --git a/plogical/virtualHostUtilities.py b/plogical/virtualHostUtilities.py index c7e08214e..53d2d9469 100644 --- a/plogical/virtualHostUtilities.py +++ b/plogical/virtualHostUtilities.py @@ -51,6 +51,10 @@ class virtualHostUtilities: redisConf = '/usr/local/lsws/conf/dvhost_redis.conf' vhostConfPath = '/usr/local/lsws/conf' + + + + @staticmethod def OnBoardingHostName(Domain, tempStatusPath): import json