Files
CyberPanel/plogical/mailUtilities.py

609 lines
20 KiB
Python
Raw Normal View History

2018-06-05 00:53:45 +05:00
import os,sys
sys.path.append('/usr/local/CyberCP')
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
django.setup()
2017-12-09 22:30:10 +05:00
import os.path
import shutil
import CyberCPLogFileWriter as logging
import subprocess
import argparse
import shlex
2018-06-05 00:53:45 +05:00
from mailServer.models import Domains,EUsers
from emailPremium.models import DomainLimits, EmailLimits
2018-06-05 00:53:45 +05:00
from websiteFunctions.models import Websites
2018-11-12 18:39:04 +05:00
from processUtilities import ProcessUtilities
2017-12-09 22:30:10 +05:00
class mailUtilities:
2018-05-08 21:25:37 +05:00
installLogPath = "/home/cyberpanel/openDKIMInstallLog"
2018-06-25 05:45:38 +05:00
spamassassinInstallLogPath = "/home/cyberpanel/spamassassinInstallLogPath"
2018-05-08 21:25:37 +05:00
cyberPanelHome = "/home/cyberpanel"
2018-05-03 01:22:28 +05:00
2017-12-09 22:30:10 +05:00
@staticmethod
2018-06-05 00:53:45 +05:00
def createEmailAccount(domain, userName, password):
2017-12-09 22:30:10 +05:00
try:
2018-06-05 00:53:45 +05:00
## Check if already exists
finalEmailUsername = userName + "@" + domain
if EUsers.objects.filter(email=finalEmailUsername).exists():
raise BaseException("This account already exists!")
## Check for email limits.
website = Websites.objects.get(domain=domain)
try:
if not Domains.objects.filter(domain=domain).exists():
newEmailDomain = Domains(domainOwner=website, domain=domain)
newEmailDomain.save()
if not DomainLimits.objects.filter(domain=newEmailDomain).exists():
domainLimits = DomainLimits(domain=newEmailDomain)
domainLimits.save()
2018-06-05 00:53:45 +05:00
if website.package.emailAccounts == 0 or (
newEmailDomain.eusers_set.all().count() < website.package.emailAccounts):
pass
else:
raise BaseException("Exceeded maximum amount of email accounts allowed for the package.")
except:
emailDomain = Domains.objects.get(domain=domain)
if website.package.emailAccounts == 0 or (
emailDomain.eusers_set.all().count() < website.package.emailAccounts):
pass
else:
raise BaseException("Exceeded maximum amount of email accounts allowed for the package.")
## After effects
2017-12-09 22:30:10 +05:00
path = "/usr/local/CyberCP/install/rainloop/cyberpanel.net.ini"
if not os.path.exists("/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/domains/"):
os.makedirs("/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/domains/")
finalPath = "/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/domains/" + domain + ".ini"
if not os.path.exists(finalPath):
shutil.copy(path, finalPath)
2018-10-12 18:18:10 +05:00
command = 'chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop'
2017-12-09 22:30:10 +05:00
cmd = shlex.split(command)
res = subprocess.call(cmd)
2018-10-12 18:18:10 +05:00
command = 'chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data/_data_'
2017-12-09 22:30:10 +05:00
cmd = shlex.split(command)
res = subprocess.call(cmd)
2018-06-05 00:53:45 +05:00
## After effects ends
emailDomain = Domains.objects.get(domain=domain)
emailAcct = EUsers(emailOwner=emailDomain, email=finalEmailUsername, password=password)
emailAcct.save()
emailLimits = EmailLimits(email=emailAcct)
emailLimits.save()
2017-12-09 22:30:10 +05:00
print "1,None"
2018-06-05 00:53:45 +05:00
return 1,"None"
2017-12-09 22:30:10 +05:00
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [createEmailAccount]")
print "0," + str(msg)
2018-06-05 00:53:45 +05:00
return 0, str(msg)
2017-12-09 22:30:10 +05:00
2018-06-05 00:53:45 +05:00
@staticmethod
def deleteEmailAccount(email):
try:
email = EUsers(email=email)
email.delete()
return 1, 'None'
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [deleteEmailAccount]")
return 0, str(msg)
@staticmethod
def getEmailAccounts(virtualHostName):
try:
emailDomain = Domains.objects.get(domain=virtualHostName)
return emailDomain.eusers_set.all()
except:
return 0
@staticmethod
def changeEmailPassword(email, newPassword):
try:
changePass = EUsers.objects.get(email=email)
changePass.password = newPassword
changePass.save()
return 0,'None'
except BaseException, msg:
return 0, str(msg)
2017-12-09 22:30:10 +05:00
2018-05-01 00:49:47 +05:00
@staticmethod
def setupDKIM(virtualHostName):
try:
## Generate DKIM Keys
2018-06-11 21:04:55 +05:00
import tldextract
2018-11-21 14:50:27 +05:00
#extractDomain = tldextract.extract(virtualHostName)
#virtualHostName = extractDomain.domain + '.' + extractDomain.suffix
2018-06-11 21:04:55 +05:00
2018-05-01 00:49:47 +05:00
if os.path.exists("/etc/opendkim/keys/" + virtualHostName):
return 1, "None"
os.mkdir("/etc/opendkim/keys/" + virtualHostName)
## Generate keys
2018-06-05 00:53:45 +05:00
FNULL = open(os.devnull, 'w')
2018-05-01 00:49:47 +05:00
command = "opendkim-genkey -D /etc/opendkim/keys/" + virtualHostName + " -d " + virtualHostName + " -s default"
2018-06-05 00:53:45 +05:00
subprocess.call(shlex.split(command),stdout=FNULL, stderr=subprocess.STDOUT)
2018-05-01 00:49:47 +05:00
## Fix permissions
command = "chown -R root:opendkim /etc/opendkim/keys/" + virtualHostName
subprocess.call(shlex.split(command))
command = "chmod 640 /etc/opendkim/keys/" + virtualHostName + "/default.private"
subprocess.call(shlex.split(command))
command = "chmod 644 /etc/opendkim/keys/" + virtualHostName + "/default.txt"
subprocess.call(shlex.split(command))
## Edit key file
keyTable = "/etc/opendkim/KeyTable"
configToWrite = "default._domainkey." + virtualHostName + " " + virtualHostName + ":default:/etc/opendkim/keys/" + virtualHostName + "/default.private\n"
writeToFile = open(keyTable, 'a')
writeToFile.write(configToWrite)
writeToFile.close()
## Edit signing table
signingTable = "/etc/opendkim/SigningTable"
configToWrite = "*@" + virtualHostName + " default._domainkey." + virtualHostName + "\n"
writeToFile = open(signingTable, 'a')
writeToFile.write(configToWrite)
writeToFile.close()
## Trusted hosts
trustedHosts = "/etc/opendkim/TrustedHosts"
configToWrite = virtualHostName + "\n"
writeToFile = open(trustedHosts, 'a')
writeToFile.write(configToWrite)
writeToFile.close()
## Restart postfix and OpenDKIM
command = "systemctl restart opendkim"
subprocess.call(shlex.split(command))
command = "systemctl restart postfix"
subprocess.call(shlex.split(command))
return 1, "None"
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [setupDKIM]")
return 0, str(msg)
@staticmethod
def checkIfDKIMInstalled():
try:
path = "/etc/opendkim.conf"
2018-05-08 21:25:37 +05:00
command = "sudo cat " + path
res = subprocess.call(shlex.split(command))
if res == 1:
2018-05-01 00:49:47 +05:00
return 0
2018-05-08 21:25:37 +05:00
else:
return 1
2018-05-01 00:49:47 +05:00
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [checkIfDKIMInstalled]")
return 0
2018-05-03 01:22:28 +05:00
@staticmethod
def generateKeys(domain):
try:
result = mailUtilities.setupDKIM(domain)
if result[0] == 0:
raise BaseException(result[1])
else:
print "1,None"
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [generateKeys]")
print "0," + str(msg)
@staticmethod
def configureOpenDKIM():
try:
## Configure OpenDKIM specific settings
openDKIMConfigurePath = "/etc/opendkim.conf"
configData = """
Mode sv
Canonicalization relaxed/simple
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
"""
writeToFile = open(openDKIMConfigurePath, 'a')
writeToFile.write(configData)
writeToFile.close()
## Configure postfix specific settings
postfixFilePath = "/etc/postfix/main.cf"
configData = """
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
"""
writeToFile = open(postfixFilePath, 'a')
writeToFile.write(configData)
writeToFile.close()
#### Restarting Postfix and OpenDKIM
command = "systemctl start opendkim"
subprocess.call(shlex.split(command))
command = "systemctl enable opendkim"
subprocess.call(shlex.split(command))
##
command = "systemctl start postfix"
subprocess.call(shlex.split(command))
print "1,None"
return
except OSError, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureOpenDKIM]")
print "0," + str(msg)
return
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureOpenDKIM]")
print "0," + str(msg)
return
2018-05-08 21:25:37 +05:00
@staticmethod
def checkHome():
try:
try:
2018-11-26 02:32:30 +05:00
FNULL = open(os.devnull, 'w')
2018-05-08 21:25:37 +05:00
command = "sudo mkdir " + mailUtilities.cyberPanelHome
2018-11-26 02:32:30 +05:00
subprocess.call(shlex.split(command), stdout=FNULL)
2018-05-08 21:25:37 +05:00
command = "sudo chown -R cyberpanel:cyberpanel " + mailUtilities.cyberPanelHome
2018-11-26 02:32:30 +05:00
subprocess.call(shlex.split(command), stdout=FNULL)
2018-05-08 21:25:37 +05:00
except:
command = "sudo chown -R cyberpanel:cyberpanel " + mailUtilities.cyberPanelHome
2018-11-26 02:32:30 +05:00
subprocess.call(shlex.split(command), stdout=FNULL)
2018-05-08 21:25:37 +05:00
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [checkHome]")
2018-05-03 01:22:28 +05:00
@staticmethod
def installOpenDKIM(install, openDKIMINstall):
try:
2018-05-08 21:25:37 +05:00
mailUtilities.checkHome()
2018-05-03 01:22:28 +05:00
command = 'sudo yum install opendkim -y'
cmd = shlex.split(command)
with open(mailUtilities.installLogPath, 'w') as f:
res = subprocess.call(cmd, stdout=f)
if res == 1:
writeToFile = open(mailUtilities.installLogPath, 'a')
writeToFile.writelines("Can not be installed.[404]\n")
writeToFile.close()
2018-05-08 21:25:37 +05:00
logging.CyberCPLogFileWriter.writeToFile("[Could not Install OpenDKIM.]")
2018-05-03 01:22:28 +05:00
return 0
else:
writeToFile = open(mailUtilities.installLogPath, 'a')
writeToFile.writelines("OpenDKIM Installed.[200]\n")
writeToFile.close()
return 1
except BaseException, msg:
2018-05-08 21:25:37 +05:00
writeToFile = open(mailUtilities.installLogPath, 'a')
writeToFile.writelines("Can not be installed.[404]\n")
writeToFile.close()
2018-05-03 01:22:28 +05:00
logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[installOpenDKIM]")
2018-05-24 23:37:10 +05:00
@staticmethod
def restartServices():
try:
command = 'systemctl restart postfix'
subprocess.call(shlex.split(command))
command = 'systemctl restart dovecot'
subprocess.call(shlex.split(command))
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [restartServices]")
2018-06-25 05:45:38 +05:00
@staticmethod
def installSpamAssassin(install, SpamAssassin):
try:
mailUtilities.checkHome()
2018-11-12 18:39:04 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.centos:
command = 'sudo yum install spamassassin -y'
else:
command = 'sudo apt-get install spamassassin spamc -y'
2018-06-25 05:45:38 +05:00
cmd = shlex.split(command)
with open(mailUtilities.spamassassinInstallLogPath, 'w') as f:
res = subprocess.call(cmd, stdout=f)
if res == 1:
writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a')
writeToFile.writelines("Can not be installed.[404]\n")
writeToFile.close()
logging.CyberCPLogFileWriter.writeToFile("[Could not Install SpamAssassin.]")
return 0
else:
writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a')
writeToFile.writelines("SpamAssassin Installed.[200]\n")
writeToFile.close()
return 1
except BaseException, msg:
writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a')
writeToFile.writelines("Can not be installed.[404]\n")
writeToFile.close()
logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[installSpamAssassin]")
@staticmethod
def checkIfSpamAssassinInstalled():
try:
path = "/etc/mail/spamassassin/local.cf"
command = "sudo cat " + path
res = subprocess.call(shlex.split(command))
if res == 1:
return 0
else:
return 1
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [checkIfSpamAssassinInstalled]")
return 0
@staticmethod
def configureSpamAssassin():
try:
command = "groupadd spamd"
subprocess.call(shlex.split(command))
command = "useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd"
subprocess.call(shlex.split(command))
##
command = "chown spamd:spamd /var/log/spamassassin"
subprocess.call(shlex.split(command))
command = "systemctl enable spamassassin"
subprocess.call(shlex.split(command))
command = "systemctl start spamassassin"
subprocess.call(shlex.split(command))
## Configuration to postfix
postfixConf = '/etc/postfix/master.cf'
data = open(postfixConf, 'r').readlines()
writeToFile = open(postfixConf, 'w')
checker = 1
for items in data:
if items.find('smtp') > - 1 and items.find('inet') > - 1 and items.find('smtpd') > - 1 and checker == 1:
writeToFile.writelines(items.strip('\n') + ' -o content_filter=spamassassin\n')
checker = 0
else:
writeToFile.writelines(items)
writeToFile.writelines('spamassassin unix - n n - - pipe flags=R user=spamd argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}')
writeToFile.close()
command = 'systemctl restart postfix'
subprocess.call(shlex.split(command))
print "1,None"
return
except OSError, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureSpamAssassin]")
print "0," + str(msg)
return
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureSpamAssassin]")
print "0," + str(msg)
return
@staticmethod
def saveSpamAssassinConfigs(tempConfigPath):
try:
data = open(tempConfigPath).readlines()
os.remove(tempConfigPath)
confFile = "/etc/mail/spamassassin/local.cf"
confData = open(confFile).readlines()
conf = open(confFile, 'w')
rsCheck = 0
for items in confData:
if items.find('report_safe ') > -1:
conf.writelines(data[0])
continue
elif items.find('required_hits ') > -1:
conf.writelines(data[1])
continue
elif items.find('rewrite_header ') > -1:
conf.writelines(data[2])
continue
elif items.find('required_score ') > -1:
conf.writelines(data[3])
rsCheck = 1
continue
if rsCheck == 0:
conf.writelines(data[3])
conf.close()
command = 'systemctl restart spamassassin'
subprocess.call(shlex.split(command))
print "1,None"
return
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [saveSpamAssassinConfigs]")
print "0," + str(msg)
2018-06-27 00:16:50 +05:00
@staticmethod
def savePolicyServerStatus(install):
try:
postfixPath = '/etc/postfix/main.cf'
if install == '1':
if not os.path.exists('/etc/systemd/system/cpecs.service'):
shutil.copy("/usr/local/CyberCP/postfixSenderPolicy/cpecs.service", "/etc/systemd/system/cpecs.service")
2018-10-12 18:18:10 +05:00
command = 'systemctl enable cpecs'
subprocess.call(shlex.split(command))
2018-06-27 00:16:50 +05:00
command = 'systemctl start cpecs'
subprocess.call(shlex.split(command))
writeToFile = open(postfixPath, 'a')
writeToFile.writelines('smtpd_data_restrictions = check_policy_service unix:/var/log/policyServerSocket\n')
2018-10-13 18:31:47 +05:00
writeToFile.writelines('smtpd_policy_service_default_action = DUNNO\n')
2018-06-27 00:16:50 +05:00
writeToFile.close()
command = 'systemctl restart postfix'
subprocess.call(shlex.split(command))
else:
data = open(postfixPath, 'r').readlines()
writeToFile = open(postfixPath, 'w')
for items in data:
if items.find('check_policy_service unix:/var/log/policyServerSocket') > -1:
2018-06-27 00:16:50 +05:00
continue
2018-10-13 18:31:47 +05:00
elif items.find('smtpd_policy_service_default_action = DUNNO') > -1:
continue
2018-06-27 00:16:50 +05:00
else:
writeToFile.writelines(items)
writeToFile.close()
command = 'systemctl stop cpecs'
subprocess.call(shlex.split(command))
command = 'systemctl restart postfix'
subprocess.call(shlex.split(command))
print "1,None"
return
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(
str(msg) + " [savePolicyServerStatus]")
print "0," + str(msg)
2018-05-01 00:49:47 +05:00
2017-12-09 22:30:10 +05:00
def main():
parser = argparse.ArgumentParser(description='CyberPanel Installer')
parser.add_argument('function', help='Specific a function to call!')
parser.add_argument('--domain', help='Domain name!')
2018-06-05 00:53:45 +05:00
parser.add_argument('--userName', help='Email Username!')
parser.add_argument('--password', help='Email password!')
2018-06-25 05:45:38 +05:00
parser.add_argument('--tempConfigPath', help='Temporary Configuration Path!')
2018-06-27 00:16:50 +05:00
parser.add_argument('--install', help='Enable/Disable Policy Server!')
2018-06-05 00:53:45 +05:00
2017-12-09 22:30:10 +05:00
args = parser.parse_args()
if args.function == "createEmailAccount":
2018-06-05 00:53:45 +05:00
mailUtilities.createEmailAccount(args.domain, args.userName, args.password)
2018-05-03 01:22:28 +05:00
elif args.function == "generateKeys":
mailUtilities.generateKeys(args.domain)
elif args.function == "configureOpenDKIM":
mailUtilities.configureOpenDKIM()
2018-06-25 05:45:38 +05:00
elif args.function == "configureSpamAssassin":
mailUtilities.configureSpamAssassin()
elif args.function == "saveSpamAssassinConfigs":
mailUtilities.saveSpamAssassinConfigs(args.tempConfigPath)
2018-06-27 00:16:50 +05:00
elif args.function == 'savePolicyServerStatus':
mailUtilities.savePolicyServerStatus(args.install)
2017-12-09 22:30:10 +05:00
if __name__ == "__main__":
main()