Dre4m Shell
Server IP : 85.214.239.14  /  Your IP : 3.135.204.160
Web Server : Apache/2.4.62 (Debian)
System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.18
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /srv/automx/automx-master/src/automx/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : /srv/automx/automx-master/src/automx/view.py
"""
automx - auto configuration service
Copyright (c) 2011-2013 [*] sys4 AG

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import sys
import uuid
import logging

from lxml import etree
from lxml.etree import XMLSyntaxError
from xml.parsers.expat import ExpatError

try:
    # noinspection PyUnresolvedReferences
    from plistlib import load, dumps, FMT_XML
except ImportError:
    # noinspection PyPep8Naming
    from plistlib import readPlist, writePlistToString


__version__ = '1.1.1'
__author__ = "Christian Roessner, Patrick Ben Koetter"
__copyright__ = "Copyright (c) 2011-2015 [*] sys4 AG"


class View(object):
    """
    The view class uses the data structure built with the model class Config.
    It can convert data into different XML outputs. It currently supports
    AutoDiscover as found in the Microsoft world as well as Autoconfig, which
    is used in Mozilla Thunderbird and several other open-source MUAs. It also
    supports .mobileconfig profile support as found on iOS devices. These
    profiles can also be used on Mac OS X Mail.app

    """

    def __init__(self, model, schema, subschema):
        self.__model = model
        self.__schema = schema
        self.__subschema = subschema

        self.__xml = None
        self.__plist = None

    # noinspection PyPep8Naming
    def __build_xml_plist_tree(self):
        if self.__schema in self.__model.domain:
            if self.__schema in ("autodiscover", "autoconfig"):
                path = self.__model.domain[self.__schema]
                try:
                    tree = etree.parse(path)
                    root = tree.getroot()
                    self.__xml = root
                except XMLSyntaxError:
                    logging.error("Syntax error in file %s" % path)

            elif self.__schema == "mobileconfig":
                path = self.__model.domain[self.__schema]
                try:
                    if sys.version_info < (3,):
                        plist_tmp = readPlist(path)
                    else:
                        plist_tmp = load(path)
                    plist = plist_tmp.copy()
                    self.__plist = plist
                except ExpatError:
                    logging.error("Syntax error in file %s" % path)

        elif self.__schema == "autodiscover":
            # define namespace constant
            NS_AutoDiscover = ("http://schemas.microsoft.com/exchange/"
                               "autodiscover/responseschema/2006")

            if self.__subschema == "outlook":
                NS_Response = ("http://schemas.microsoft.com/exchange/"
                               "autodiscover/outlook/responseschema/2006a")

                root = etree.Element("Autodiscover", xmlns=NS_AutoDiscover)
                response = etree.SubElement(root,
                                            "Response",
                                            xmlns=NS_Response)

                if ("display_name" in self.__model.domain or
                        ("smtp" in self.__model.domain and
                         "smtp_author" in self.__model.domain["smtp"][0])):

                    user = etree.SubElement(response, "User")

                    if "display_name" in self.__model.domain:
                        displayname = etree.SubElement(user, "DisplayName")
                        displayname.text = self.__model.domain["display_name"]

                    if "smtp" in self.__model.domain:
                        smtp = self.__model.domain["smtp"]

                        if "smtp_author" in smtp[0]:
                            email = smtp[0]["smtp_author"]

                            smtp_author = etree.SubElement(
                                user, "AutoDiscoverSMTPAddress")
                            smtp_author.text = email

                account = etree.SubElement(response, "Account")

                if "account_type" in self.__model.domain:
                    account_type = etree.SubElement(account, "AccountType")
                    account_type.text = self.__model.domain["account_type"]
                else:
                    raise Exception("Missing attribute <account_type>")

                if "action" in self.__model.domain:
                    action = etree.SubElement(account, "Action")
                    action.text = self.__model.domain["action"]
                else:
                    raise Exception("Missing attribute <action>")

                for key, value in self.__model.domain.items():
                    if key in ("smtp", "imap", "pop", "caldav", "carddav", "ox"):
                        if len(value) != 0:
                            protocol = etree.SubElement(account, "Protocol")
                            self.__service(key, protocol)

                self.__xml = root

            elif self.__subschema == "mobile":
                NS_Response = ("http://schemas.microsoft.com/exchange/"
                               "autodiscover/mobilesync/responseschema/2006")

                root = etree.Element("Autodiscover", xmlns=NS_AutoDiscover)
                response = etree.SubElement(root,
                                            "Response",
                                            xmlns=NS_Response)

                # TODO: do we need a Culture option?
                culture = etree.SubElement(response, "Culture")
                culture.text = "en:us"

                user = etree.SubElement(response, "User")

                if "display_name" in self.__model.domain:
                    displayname = etree.SubElement(user, "DisplayName")
                    displayname.text = self.__model.domain["display_name"]

                emailaddress = etree.SubElement(user, "EmailAddress")
                emailaddress.text = self.__model.domain["emailaddress"]

                action = etree.SubElement(response, "Action")

                settings = etree.SubElement(action, "Settings")

                server = etree.SubElement(settings, "Server")

                servertype = etree.SubElement(server, "Type")
                servertype.text = "MobileSync"

                if "server_url" in self.__model.domain:
                    serverurl = etree.SubElement(server, "Url")
                    serverurl.text = self.__model.domain["server_url"]

                if "server_name" in self.__model.domain:
                    servername = etree.SubElement(server, "Name")
                    servername.text = self.__model.domain["server_name"]
                elif "server_url" in self.__model.domain:
                    servername = etree.SubElement(server, "Name")
                    servername.text = self.__model.domain["server_url"]

                self.__xml = root

            else:
                return

        elif self.__schema == "autoconfig":
            root = etree.Element("clientConfig", version="1.1")

            provider = etree.SubElement(root,
                                        "emailProvider",
                                        id=self.__model.provider)

            domain = etree.SubElement(provider, "domain")
            if "domain" in self.__model.domain:
                domain.text = self.__model.domain["domain"]

            display_name = etree.SubElement(provider, "displayName")
            if "account_name" in self.__model.domain:
                display_name.text = self.__model.domain["account_name"]

            display_short = etree.SubElement(provider, "displayShortName")
            if "account_name_short" in self.__model.domain:
                display_short.text = self.__model.domain["account_name_short"]

            for key, value in self.__model.domain.items():
                if key in ("smtp", "imap", "pop"):
                    if len(value) != 0:
                        self.__service(key, provider)

            self.__xml = root

        elif self.__schema == "mobileconfig":
            proto = dict()

            # We only support IMAP or POP3.
            service_configured = False

            for key, value in self.__model.domain.items():
                if not service_configured and key == "imap":
                    if len(value) != 0:
                        self.__service(key, None, proto)
                        service_configured = True

                elif not service_configured and key == "pop":
                    if len(value) != 0:
                        self.__service(key, None, proto)
                        service_configured = True

                if key == "smtp":
                    if len(value) != 0:
                        self.__service(key, None, proto)

            if "account_name" in self.__model.domain:
                org = self.__model.domain["account_name"]
            else:
                org = self.__model.provider

            email_account_name = self.__model.cn
            if "display_name" in self.__model.domain:
                if self.__model.cn == "":
                    email_account_name = self.__model.domain["display_name"]

            rev_provider = self.__model.provider.split(".")
            rev_provider = ".".join(rev_provider[::-1])
            rev_email = self.__model.emailaddress.split("@")
            rev_email = ".".join(rev_email[::-1])
            payload_identifier = ("org.automx.mail." +
                                  rev_provider +
                                  "." +
                                  rev_email)

            s = dict(EmailAccountDescription=org,
                     EmailAccountName=email_account_name,
                     EmailAccountType=proto["type"],
                     EmailAddress=self.__model.emailaddress,
                     IncomingMailServerAuthentication=proto["in_auth"],
                     IncomingMailServerHostName=proto["in_server"],
                     IncomingMailServerPortNumber=proto["in_port"],
                     IncomingMailServerUseSSL=proto["in_encryption"],
                     IncomingMailServerUsername=proto["in_username"],
                     IncomingPassword=self.__model.password,
                     OutgoingMailServerAuthentication=proto["out_auth"],
                     OutgoingMailServerHostName=proto["out_server"],
                     OutgoingMailServerPortNumber=proto["out_port"],
                     OutgoingMailServerUseSSL=proto["out_encryption"],
                     OutgoingMailServerUsername=proto["out_username"],
                     OutgoingPasswordSameAsIncomingPassword=True,
                     PayloadDescription="Configure email account.",
                     PayloadDisplayName="IMAP Account (%s)" % org,
                     PayloadIdentifier=payload_identifier,
                     PayloadOrganization=self.__model.provider,
                     PayloadType="com.apple.mail.managed",
                     PayloadUUID=str(uuid.uuid4()),
                     PayloadVersion=1,
                     PreventAppSheet=False,
                     PreventMove=False,
                     SMIMEEnabled=False)

            self.__plist = dict(PayloadContent=[s],
                                PayloadDescription="Automx Email",
                                PayloadDisplayName=org,
                                PayloadIdentifier=payload_identifier,
                                PayloadOrganization=self.__model.provider,
                                PayloadRemovalDisallowed=False,
                                PayloadType="Configuration",
                                PayloadUUID=str(uuid.uuid4()),
                                PayloadVersion=1)

    def __service(self, service, root, proto=None):
        l = self.__model.domain[service]

        if self.__schema == "autodiscover":
            # we assume, autodiscover only supports single protocols! So we
            # only use the first defined list element
            elem = l[0]

            c = etree.SubElement(root, "Type")

            s_type = None
            if service in ("smtp", "imap"):
                s_type = service.upper()
            elif service in "pop":
                s_type = "POP3"
            elif service in "caldav":
                s_type = "CalDAV"
            elif service in "carddav":
                s_type = "CardDAV"
            elif service in "ox":
                s_type = "X-OX-APPSUITE"

            c.text = s_type

            if service + "_server" in elem:
                c = etree.SubElement(root, "Server")
                c.text = elem[service + "_server"]

            if service + "_port" in elem:
                c = etree.SubElement(root, "Port")
                c.text = elem[service + "_port"]

            c = etree.SubElement(root, "DomainRequired")
            if service + "_domain_required" in elem:
                c.text = elem[service + "_domain_required"]
            else:
                c.text = "off"
            if service + "_domain_name" in elem:
                c = etree.SubElement(root, "DomainName")
                c.text = elem[service + "_domain_name"]

            if service + "_auth_identity" in elem:
                c = etree.SubElement(root, "LoginName")
                c.text = elem[service + "_auth_identity"]

            if service + "_auth" in elem:
                c = etree.SubElement(root, "SPA")

                value = elem[service + "_auth"]

                if value != "cleartext":
                    spa = "on"
                else:
                    spa = "off"

                c.text = spa

            if service + "_encryption" in elem:
                c = etree.SubElement(root, "Encryption")

                value = elem[service + "_encryption"]

                if value == "none":
                    ssl = "None"
                elif value == "ssl":
                    ssl = "SSL"
                elif value == "starttls":
                    ssl = "TLS"
                elif value == "auto":
                    ssl = "Auto"
                else:
                    # anything that we can not understand leads into "None"
                    ssl = "None"

                c.text = ssl

            c = etree.SubElement(root, "AuthRequired")
            if service + "_auth" in elem:
                c.text = "on"
            else:
                c.text = "off"

            if service + "_expiration_date" in elem:
                c = etree.SubElement(root, "ExpirationDate")
                c.text = elem[service + "_expiration_date"]

            if service + "_refresh_ttl" in elem:
                c = etree.SubElement(root, "TTL")
                c.text = elem[service + "_refresh_ttl"]

            if service == "smtp":
                if (service + "_auth" in elem and
                        elem[service + "_auth"] == "smtp-after-pop"):
                    c = etree.SubElement(root, "SMTPLast")
                    c.text = "on"

        elif self.__schema == "autoconfig":
            for elem in iter(l):
                if service == "smtp":
                    sub_root = etree.SubElement(root,
                                                "outgoingServer",
                                                type=service)
                elif service == "imap":
                    sub_root = etree.SubElement(root,
                                                "incomingServer",
                                                type=service)
                elif service == "pop":
                    sub_root = etree.SubElement(root,
                                                "incomingServer",
                                                type="pop3")

                if service + "_server" in elem:
                    c = etree.SubElement(sub_root, "hostname")
                    c.text = elem[service + "_server"]

                if service + "_port" in elem:
                    c = etree.SubElement(sub_root, "port")
                    c.text = elem[service + "_port"]

                if service + "_encryption" in elem:
                    c = etree.SubElement(sub_root, "socketType")

                    value = elem[service + "_encryption"]

                    if value in ("ssl", "starttls"):
                        c.text = value.upper()
                    elif value in ("none", "auto"):
                        # autoconfig does not know anything about auto
                        c.text = "plain"

                if service + "_auth" in elem:
                    c = etree.SubElement(sub_root, "authentication")

                    value = elem[service + "_auth"]
                    result = ""

                    if value == "cleartext":
                        result = "password-cleartext"
                    elif value == "encrypted":
                        result = "password-encrypted"
                    elif value == "ntlm":
                        result = "NTLM"
                    elif value == "gssapi":
                        result = "GSSAPI"
                    elif value == "client-ip-address":
                        result = "client-IP-address"
                    elif value == "tls-client-cert":
                        result = "TLS-client-cert"
                    elif value == "none":
                        result = "none"
                    elif value == "smtp-after-pop":
                        if service == "smtp":
                            result = "SMTP-after-POP"

                    c.text = result

                if service + "_auth_identity" in elem:
                    c = etree.SubElement(sub_root, "username")
                    c.text = elem[service + "_auth_identity"]

                if service == "smtp":
                    if service + "_default" in elem:
                        value = elem[service + "_default"]

                        c = etree.SubElement(sub_root,
                                             "useGlobalPreferredServer")
                        c.text = value.lower()

        elif self.__schema == "mobileconfig":
            # see autodiscover comment above
            elem = l[0]

            if service == "imap":
                proto["type"] = "EmailTypeIMAP"
            if service == "pop":
                proto["type"] = "EmailTypePOP"

            if service + "_server" in elem:
                if service in ("imap", "pop"):
                    proto["in_server"] = elem[service + "_server"]
                elif service == "smtp":
                    proto["out_server"] = elem[service + "_server"]

            if service + "_port" in elem:
                if service in ("imap", "pop"):
                    proto["in_port"] = int(elem[service + "_port"])
                elif service == "smtp":
                    proto["out_port"] = int(elem[service + "_port"])

            if service + "_auth_identity" in elem:
                if service in ("imap", "pop"):
                    proto["in_username"] = elem[service + "_auth_identity"]
                elif service == "smtp":
                    proto["out_username"] = elem[service + "_auth_identity"]

            if service + "_auth" in elem:
                value = elem[service + "_auth"]
                result = ""

                if value == "cleartext":
                    result = "EmailAuthPassword"
                elif value == "encrypted":
                    # We currently do not support EmailAuthHTTPMD5
                    result = "EmailAuthCRAMMD5"
                elif value == "ntlm":
                    result = "EmailAuthNTLM"
                elif value == "gssapi":
                    # Not supported
                    pass
                elif value == "client-ip-address":
                    # Not supported
                    pass
                elif value == "tls-client-cert":
                    # Not supported
                    pass
                elif value == "none":
                    result = "EmailAuthNone"

                if service in ("imap", "pop"):
                    proto["in_auth"] = result
                elif service == "smtp":
                    proto["out_auth"] = result

            if service + "_encryption" in elem:
                value = elem[service + "_encryption"]

                if value in ("ssl", "starttls"):
                    if service in ("imap", "pop"):
                        proto["in_encryption"] = True
                    elif service == "smtp":
                        proto["out_encryption"] = True
                else:
                    if service in ("imap", "pop"):
                        proto["in_encryption"] = False
                    elif service == "smtp":
                        proto["out_encryption"] = False

    def render(self):
        """Return the XML result of the view as a character string.
        """
        self.__build_xml_plist_tree()

        if self.__xml is not None:
            return etree.tostring(self.__xml,
                                  xml_declaration=True,
                                  method="xml",
                                  encoding="utf-8",
                                  pretty_print=True)

        elif self.__plist is not None:
            if sys.version_info < (3,):
                plist_unsigned = writePlistToString(self.__plist)
            else:
                # noinspection PyArgumentList
                plist_unsigned = dumps(self.__plist, fmt=FMT_XML)

            # Old M2Crypto that is not ported yet to Python3
            """
                    sign_cert = self.__model.domain["sign_cert"]
                    sign_key = self.__model.domain["sign_key"]

                    buffer = M2Crypto.BIO.MemoryBuffer(plist_unsigned)
                    signer = M2Crypto.SMIME.SMIME()
                    s = M2Crypto.X509.X509_Stack()

                    cert_handle = open(sign_cert).read()
                    certificates = re.finditer(r"-----BEGIN CERTIFICATE-----"
                                                ".*?-----END CERTIFICATE-----",
                                                cert_handle, re.S)

                    # First certificate is for signing!
                    # Rest is intermediate cert chain!
                    certificates.next()
                    for match in certificates:
                        s.push(M2Crypto.X509.load_cert_string(match.group(0)))
                    signer.set_x509_stack(s)

                    # Load key and _first_ certificate
                    try:
                        signer.load_key(sign_key, sign_cert)
                    except M2Crypto.BIO.BIOError:
                        logging.error("Cannot access %s or %s. Not signing!"
                                      % (sign_cert, sign_key))
                        return plist_unsigned

                    p7 = signer.sign(buffer)
                    output = M2Crypto.BIO.MemoryBuffer()
                    p7.write_der(output)
                    plist_signed = output.getvalue()

                    return plist_signed
            """

            if "sign_mobileconfig" in self.__model.domain:
                if (self.__model.domain["sign_mobileconfig"] is True and
                        "sign_cert" in self.__model.domain and
                        "sign_key" in self.__model.domain):

                    sign_cert = self.__model.domain["sign_cert"]
                    sign_key = self.__model.domain["sign_key"]

                    if "sign_more_certs" in self.__model.domain:
                        extra = " -certfile " + self.__model.domain[
                            "sign_more_certs"]
                    else:
                        extra = ""

                    import subprocess as s

                    cmd = self.__model.openssl + \
                        " smime -sign -nodetach -outform der -aes-256-cbc" \
                        " -signer " + sign_cert + " -inkey " + sign_key + \
                        extra
                    process = s.Popen(
                        cmd.split(), stdin=s.PIPE, stdout=s.PIPE, stderr=s.PIPE)

                    plist_signed, errors = process.communicate(
                        input=plist_unsigned)
                    if errors not in (b"", None):
                        logging.warning("openssl: %s", str(errors))

                    return plist_signed
                else:
                    logging.info("Not signing!")

            return plist_unsigned
        else:
            return ""

# vim: expandtab ts=4 sw=4

Anon7 - 2022
AnonSec Team