File automx-ox.patch of Package automx
diff --git a/src/automx/config.py b/src/automx/config.py
index 1da4d3a..2ae555b 100644
--- a/src/automx/config.py
+++ b/src/automx/config.py
@@ -60,47 +60,47 @@ class Config(object, ConfigParser.RawConfigParser):
independend from the view. It may query different backends to gather all
required information needed to generate XML output later on in the view
class.
-
+
It uses a OrderdDict to guarentee the correct service order that is needed
in the XML output. This said means that it is a difference, if a service
like IMAP is configured before POP3 or upside down, because a MUA follows
this order.
-
- The class currently support smtp, pop and imap services.
-
+
+ The class currently support smtp, pop, imap, carddav, caldav and ox services.
+
The class currently supports the following backends:
-
+
-> global - This backend tells automx to use the global section
-
+
-> static - all kind of service information that can be sent directly to
the MUA
-
+
-> filter - This backend can execute commands and collects results from
stdout. The result may be "", which means we skip further
searching. It may return data, which should point to a section
that we try to follow.
-
+
-> ldap - Read all kind of information from LDAP servers. The result
attributes are stored in an internal dictionary and if options
later on in this backend section (is read as static backend)
do contain variables in the form ${attributename}, these are
expanded to the collected data.
-
+
-> sql - Read all kind of information from SQL servers. The result
attributes are stored in an internal dictionary. See ldpa
-
+
-> script - Execute a script and split a result into attributes, which are
stored in an internal dictionary, See ldap
-
+
-> file - Provide static files. If present, all collected data are
discarded and only the static file is sent to the remote
client. This may change in future releases.
-
+
Note: There may exist a DEFAULT section that is appended to _all_ sections
in the configuration file. That said you can do really complex
configurations that on the other hand make life easier. This section also
may contain variables, which, if found in the vars-dictionary, are used.
-
+
"""
def __init__(self, environ):
ConfigParser.RawConfigParser.__init__(self,
@@ -134,9 +134,9 @@ class Config(object, ConfigParser.RawConfigParser):
self.debug = self.getboolean("automx", "debug")
else:
self.debug = False
-
+
self.memcache = Memcache(self, environ)
-
+
# defaults
self.__emailaddress = ""
self.__cn = ""
@@ -149,27 +149,27 @@ class Config(object, ConfigParser.RawConfigParser):
# if we use dynamic backends, we might earn variables
self.__vars = dict()
-
+
def configure(self, emailaddress, cn=None, password=None):
if emailaddress is None:
return OrderedDict()
# Full email address containing local part _and_ domain
self.__emailaddress = emailaddress
-
+
# Mobileconfig
if cn is not None:
self.__cn = cn
if password is not None:
self.__password = password
-
+
# The domain that is searched in the config file
domain = emailaddress.split("@")[1]
self.__search_domain = domain
-
+
try:
provider = self.get("automx", "provider")
-
+
# provider must be a domainname
pattern = "^[0-9a-zA-Z.-]+[a-zA-Z]{2,9}$"
prog = re.compile(pattern)
@@ -179,9 +179,9 @@ class Config(object, ConfigParser.RawConfigParser):
else:
logging.error("<provider> setting broken!")
self.__automx["provider"] = "provider.broken"
-
+
tmp = self.create_list(self.get("automx", "domains"))
- self.__automx["domains"] = tmp
+ self.__automx["domains"] = tmp
except TypeError:
raise Exception("Missing options in section automx")
@@ -205,16 +205,16 @@ class Config(object, ConfigParser.RawConfigParser):
settings["domain"] = self.__search_domain
settings["emailaddress"] = self.__emailaddress
-
+
section = self.__find_section(section)
-
+
if self.has_option(section, "backend"):
if backend is None:
try:
backend = self.get(section, "backend")
except NoOptionError:
raise Exception("Missing option <backend>")
-
+
if backend in ("static", "static_append"):
for opt in iter(self.options(section)):
if opt in ("action",
@@ -234,6 +234,12 @@ class Config(object, ConfigParser.RawConfigParser):
service = self.__service(section, "imap")
elif opt == "pop":
service = self.__service(section, "pop")
+ elif opt == "carddav":
+ service = self.__service(section, "carddav")
+ elif opt == "caldav":
+ service = self.__service(section, "caldav")
+ elif opt == "ox":
+ service = self.__service(section, "ox")
elif opt == "sign_mobileconfig":
try:
settings[opt] = self.getboolean(section, opt)
@@ -248,8 +254,8 @@ class Config(object, ConfigParser.RawConfigParser):
logging.error("%s cannot read %s" % (opt, result))
else:
pass
-
- if opt in ("smtp", "imap", "pop"):
+
+ if opt in ("smtp", "imap", "pop", "caldav", "carddav", "ox"):
if backend == "static_append":
if settings.has_key(opt):
if self.debug:
@@ -321,12 +327,12 @@ class Config(object, ConfigParser.RawConfigParser):
"key",
"cacert"):
result = self.get(section, opt)
-
+
if opt in ("host", "result_attrs"):
result = self.create_list(result)
-
+
ldap_cfg[opt] = result
-
+
# Do we connect with TLS?
if ldap_cfg["usetls"].lower() in ("yes", "true", "1"):
if ldap_cfg["reqcert"] in ("never",
@@ -358,7 +364,7 @@ class Config(object, ConfigParser.RawConfigParser):
ldap_cfg["key"])
tls = True
-
+
# Are we SASL binding to our servers?
if ldap_cfg["bindmethod"] == "sasl":
mech = ldap_cfg["saslmech"]
@@ -379,7 +385,7 @@ class Config(object, ConfigParser.RawConfigParser):
auth_tokens = ldap.sasl.gssapi(ldap_cfg["authzid"])
sasl = True
-
+
con = None
for server in iter(ldap_cfg["host"]):
@@ -406,12 +412,12 @@ class Config(object, ConfigParser.RawConfigParser):
scope = ldap.SCOPE_BASE
filter = self.__replace_makro(ldap_cfg["filter"])
-
+
rid = con.search(ldap_cfg["base"],
scope,
filter,
ldap_cfg["result_attrs"])
-
+
raw_res = (None, None)
raw_res = con.result(rid, True, 60)
if raw_res[0] == None:
@@ -420,7 +426,7 @@ class Config(object, ConfigParser.RawConfigParser):
# connection established, we have results
self.__vars = dict()
-
+
# we did not receive data from LDAP
if raw_res[1] != []:
for entry in raw_res[1]:
@@ -432,7 +438,7 @@ class Config(object, ConfigParser.RawConfigParser):
logging.warning("No LDAP result from server!")
raise DataNotFoundException
- try:
+ try:
con.unbind()
except ldap.LDAPError, e:
pass
@@ -441,7 +447,7 @@ class Config(object, ConfigParser.RawConfigParser):
self.__eval_options(section, backend="static")
else:
self.__eval_options(section, backend="static_append")
-
+
elif backend in ("sql", "sql_append"):
try:
from sqlalchemy.engine import create_engine
@@ -449,7 +455,7 @@ class Config(object, ConfigParser.RawConfigParser):
raise Exception("python sqlalchemy missing")
sql_cfg = dict(host = None, query = "", result_attrs = [])
-
+
for opt in iter(self.options(section)):
if opt in ("host", "result_attrs"):
result = self.create_list(self.get(section, opt))
@@ -460,7 +466,7 @@ class Config(object, ConfigParser.RawConfigParser):
sql_cfg["query"] = self.__replace_makro(query)
else:
raise Exception("Missing option <query>")
-
+
for con in iter(sql_cfg["host"]):
try:
engine = create_engine(con)
@@ -468,7 +474,7 @@ class Config(object, ConfigParser.RawConfigParser):
except Exception, e:
logging.error("SQL: %s" % e)
continue
-
+
result = connection.execute(sql_cfg["query"])
for row in result:
keys = row.keys()
@@ -484,7 +490,7 @@ class Config(object, ConfigParser.RawConfigParser):
raise DataNotFoundException
connection.close()
-
+
break
if backend == "sql":
@@ -497,7 +503,7 @@ class Config(object, ConfigParser.RawConfigParser):
if opt in ("autoconfig", "autodiscover", "mobileconfig"):
tmp = self.get(section, opt)
result = self.__expand_vars(tmp)
-
+
if os.path.exists(result):
settings[opt] = result
@@ -564,32 +570,32 @@ class Config(object, ConfigParser.RawConfigParser):
self.__eval_options(section, backend="static")
else:
self.__eval_options(section, backend="static_append")
-
+
### backends beyond this line do not have a follow option ###
elif backend == "filter":
if self.has_option(section, "section_filter"):
tmp = self.create_list(self.get(section, "section_filter"))
special_opts = tmp
-
+
got_data = False
-
+
for special_opt in iter(special_opts):
if self.has_option(section, special_opt):
- cmd = shlex.split(self.get(section, special_opt))
+ cmd = shlex.split(self.get(section, special_opt))
for i, item in enumerate(cmd):
cmd[i] = self.__replace_makro(item)
stdout_fd = sys.__stdout__.fileno()
-
+
pipe_in, pipe_out = os.pipe()
-
+
pid = os.fork()
if pid == 0:
# child
os.close(pipe_in)
os.dup2(pipe_out, stdout_fd)
-
+
os.execvp(cmd[0], cmd)
raise Exception("ERROR in execvp()")
@@ -597,11 +603,11 @@ class Config(object, ConfigParser.RawConfigParser):
# parent
os.close(pipe_out)
recv = os.read(pipe_in, 1024)
-
+
result = os.waitpid(pid, 0)
else:
continue
-
+
# check return code
if result[1] != 0:
raise Exception("ERROR while calling filter",
@@ -617,23 +623,23 @@ class Config(object, ConfigParser.RawConfigParser):
if self.debug:
logging.debug("Email address from filter: %s"
% new_emailaddress)
-
+
got_data = True
-
- # we replace our search_domain
+
+ # we replace our search_domain
self.__search_domain = special_opt
self.__emailaddress = new_emailaddress
# recurse again, because we now have a new section
# that we need to scan
self.__eval_options(special_opt)
-
+
# we already got a result. Do not continue!
break
-
+
if not got_data:
raise DataNotFoundException
-
+
elif backend == "global":
if self.has_section("global"):
self.__eval_options("global")
@@ -656,17 +662,17 @@ class Config(object, ConfigParser.RawConfigParser):
result = self.__expand_vars(self.get(section, opt))
proto_settings[opt] = result
-
+
if self.has_option(section, service + "_port"):
opt = service + "_port"
result = self.__expand_vars(self.get(section, opt))
-
+
proto_settings[opt] = result
-
+
if self.has_option(section, service + "_encryption"):
opt = service + "_encryption"
result = self.__expand_vars(self.get(section, opt))
-
+
if result.lower() == "none":
result = "none"
elif result.lower() == "ssl":
@@ -675,13 +681,13 @@ class Config(object, ConfigParser.RawConfigParser):
result = "starttls"
elif result.lower() == "auto":
result = "auto"
-
+
proto_settings[opt] = result
-
+
if self.has_option(section, service + "_auth"):
opt = service + "_auth"
result = self.__expand_vars(self.get(section, opt))
-
+
if result.lower() == "plaintext":
result = "cleartext"
elif result.lower() == "encrypted":
@@ -700,7 +706,7 @@ class Config(object, ConfigParser.RawConfigParser):
if service == "smtp":
result = "smtp-after-pop"
# TODO: we allow bogus keys/values.
-
+
proto_settings[opt] = result
if self.has_option(section, service + "_auth_identity"):
@@ -710,13 +716,13 @@ class Config(object, ConfigParser.RawConfigParser):
else:
emaillocalpart = self.__replace_makro("%u")
proto_settings[service + "_auth_identity"] = emaillocalpart
-
+
if self.has_option(section, service + "_expiration_date"):
opt = service + "_expiration_date"
result = self.__expand_vars(self.get(section, opt))
dt = parser.parse(result, fuzzy=True)
proto_settings[opt] = dt.strftime("%Y%m%d")
-
+
if self.has_option(section, service + "_refresh_ttl"):
opt = service + "_refresh_ttl"
result = self.get(section, opt)
@@ -729,7 +735,7 @@ class Config(object, ConfigParser.RawConfigParser):
if author == "%s":
proto_settings[opt] = self.__emailaddress
-
+
if self.has_option(section, service + "_default"):
try:
opt = service + "_default"
@@ -743,16 +749,16 @@ class Config(object, ConfigParser.RawConfigParser):
pass
return proto_settings
-
+
def create_list(self, value):
result = value.split()
-
+
if len(result) > 1:
for i, item in enumerate(result):
result[i] = item.split(",")[0]
-
+
return result
-
+
def __replace_makro(self, expression):
if "%u" in expression:
user = self.__emailaddress.split("@")[0]
@@ -770,17 +776,17 @@ class Config(object, ConfigParser.RawConfigParser):
# do we have some dynamic variables?
if len(self.__vars) == 0:
return expression
-
+
def repl(mobj):
if self.__vars.has_key(mobj.group(1)):
result = self.__vars[mobj.group(1)]
-
+
if mobj.group(2) is not None:
macro = mobj.group(2)[1:]
-
+
if self.debug:
logging.debug("__expand_vars()->macro=%s" % macro)
-
+
if "@" in result:
if macro == "%u":
return result.split("@")[0]
@@ -788,9 +794,9 @@ class Config(object, ConfigParser.RawConfigParser):
return result.split("@")[1]
if macro == "%s":
return result
-
+
result = result.split("@")[1]
-
+
# now the macro may only be part of a FQDN hostname
if "." in result:
dcs = result.split(".")
@@ -799,9 +805,9 @@ class Config(object, ConfigParser.RawConfigParser):
i = int(macro[1])
if len(dcs) < i:
return ""
-
+
return dcs[-i]
-
+
return result
else:
# we always must expand variables. Even if it is the empty
@@ -812,12 +818,12 @@ class Config(object, ConfigParser.RawConfigParser):
repl,
unicode(expression, "utf-8"),
re.UNICODE)
-
+
if self.debug:
logging.debug("__expand_vars()->result=%s" % result)
-
+
return result
-
+
def __find_section(self, domain):
l = self.sections()
for section in iter(l):
@@ -825,7 +831,7 @@ class Config(object, ConfigParser.RawConfigParser):
return section
raise NoSectionError(domain)
-
+
def get_provider(self):
return self.__automx["provider"]
provider = property(fget=get_provider)
@@ -841,25 +847,25 @@ class Config(object, ConfigParser.RawConfigParser):
def get_password(self):
return self.__password
password = property(fget=get_password)
-
+
def get_emailaddress(self):
return self.__emailaddress
emailaddress = property(fget=get_emailaddress)
-
-
+
+
class Memcache(object):
-
+
def __init__(self, config, environ):
self.__config = config
self.__environ = environ
-
+
# Memcache usage is optional
self.__has_memcache = use_memcache
self.__found = False
self.__client = None
self.__current = 0
-
+
try:
if use_memcache:
self.__mc = memcache.Client([config.get("automx", "memcache")])
@@ -893,7 +899,7 @@ class Memcache(object):
self.__current += 1
self.__mc.set(self.__client, self.__current, time=ttl)
-
+
def allow_client(self):
if not self.__has_memcache:
return True
@@ -907,7 +913,7 @@ class Memcache(object):
else:
if self.__config.debug:
logging.debug("NOT TRUSTED %s" % self.__client)
-
+
if self.__config.has_option("automx", "client_error_limit"):
try:
limit = self.__config.getint("automx", "client_error_limit")
@@ -917,7 +923,7 @@ class Memcache(object):
limit = 20
else:
limit = 20
-
+
result = self.__mc.get(self.__client)
if result is not None:
@@ -937,7 +943,7 @@ class Memcache(object):
networks = self.__config.create_list(networks)
else:
networks = ("127.0.0.1", "::1/128")
-
+
for network in iter(networks):
a = ipaddr.IPAddress(self.__client)
n = ipaddr.IPNetwork(network)
diff --git a/src/automx/view.py b/src/automx/view.py
index 682c648..f792dae 100644
--- a/src/automx/view.py
+++ b/src/automx/view.py
@@ -26,7 +26,7 @@ import uuid
import logging
import M2Crypto
import re
-
+
from lxml import etree
from lxml.etree import XMLSyntaxError
from xml.parsers.expat import ExpatError
@@ -40,19 +40,19 @@ class View(object):
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
-
+
def __build_xml_plist_tree(self):
root = None
-
+
if self.__model.domain.has_key(self.__schema):
if self.__schema in ("autodiscover", "autoconfig"):
path = self.__model.domain[self.__schema]
@@ -85,45 +85,45 @@ class View(object):
response = etree.SubElement(root,
"Response",
xmlns=NS_Response)
-
+
if (self.__model.domain.has_key("display_name") or
(self.__model.domain.has_key("smtp") and
self.__model.domain["smtp"][0].has_key("smtp_author"))):
-
+
has_user = True
-
+
user = etree.SubElement(response, "User")
-
+
if self.__model.domain.has_key("display_name"):
displayname = etree.SubElement(user, "DisplayName")
displayname.text = self.__model.domain["display_name"]
-
+
if self.__model.domain.has_key("smtp"):
smtp = self.__model.domain["smtp"]
-
+
if smtp[0].has_key("smtp_author"):
email = smtp[0]["smtp_author"]
-
+
smtp_author = etree.SubElement(user,
"AutoDiscoverSMTPAddress")
smtp_author.text = email
-
+
account = etree.SubElement(response, "Account")
-
+
if self.__model.domain.has_key("account_type"):
account_type = etree.SubElement(account, "AccountType")
account_type.text = self.__model.domain["account_type"]
else:
raise Exception("Missing attribute <account_type>")
-
+
if self.__model.domain.has_key("action"):
action = etree.SubElement(account, "Action")
action.text = self.__model.domain["action"]
else:
raise Exception("Missing attribute <action>")
-
+
for key, value in self.__model.domain.iteritems():
- if key in ("smtp", "imap", "pop"):
+ if key in ("smtp", "imap", "pop", "caldav", "carddav", "ox"):
if len(value) != 0:
protocol = etree.SubElement(account, "Protocol")
self.__service(key, protocol)
@@ -138,33 +138,33 @@ class View(object):
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 self.__model.domain.has_key("display_name"):
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 self.__model.domain.has_key("server_url"):
serverurl = etree.SubElement(server, "Url")
serverurl.text = self.__model.domain["server_url"]
-
+
if self.__model.domain.has_key("server_name"):
servername = etree.SubElement(server, "Name")
servername.text = self.__model.domain["server_name"]
@@ -179,7 +179,7 @@ class View(object):
elif self.__schema == "autoconfig":
root = etree.Element("clientConfig", version="1.1")
-
+
provider = etree.SubElement(root,
"emailProvider",
id=self.__model.provider)
@@ -187,11 +187,11 @@ class View(object):
domain = etree.SubElement(provider, "domain")
if self.__model.domain.has_key("domain"):
domain.text = self.__model.domain["domain"]
-
+
display_name = etree.SubElement(provider, "displayName")
if self.__model.domain.has_key("account_name"):
display_name.text = self.__model.domain["account_name"]
-
+
display_short = etree.SubElement(provider, "displayShortName")
if self.__model.domain.has_key("account_name_short"):
display_short.text = self.__model.domain["account_name_short"]
@@ -200,7 +200,7 @@ class View(object):
if key in ("smtp", "imap", "pop"):
if len(value) != 0:
self.__service(key, provider)
-
+
self.__xml = root
elif self.__schema == "mobileconfig":
@@ -208,7 +208,7 @@ class View(object):
# We only support IMAP or POP3.
service_configured = False
-
+
for key, value in self.__model.domain.iteritems():
if not service_configured and key == "imap":
if len(value) != 0:
@@ -223,12 +223,12 @@ class View(object):
if key == "smtp":
if len(value) != 0:
self.__service(key, None, proto)
-
+
if self.__model.domain.has_key("account_name"):
org = self.__model.domain["account_name"]
else:
org = self.__model.provider
-
+
email_account_name = self.__model.cn
if self.__model.domain.has_key("display_name"):
if self.__model.cn == "":
@@ -239,10 +239,10 @@ class View(object):
rev_email = self.__model.emailaddress.split("@")
rev_email = ".".join(rev_email[::-1])
payload_identifier = ("org.automx.mail."
- + rev_provider
+ + rev_provider
+ "."
+ rev_email)
-
+
s = dict(EmailAccountDescription = org,
EmailAccountName = email_account_name,
EmailAccountType = proto["type"],
@@ -269,7 +269,7 @@ class View(object):
PreventAppSheet = False,
PreventMove = False,
SMIMEEnabled = False)
-
+
self.__plist = dict(PayloadContent = [s],
PayloadDescription = "Automx Email",
PayloadDisplayName = org,
@@ -287,14 +287,20 @@ class View(object):
# we assume, autodiscover only supports single protocols! So we
# only use the first defined list element
elem = l[0]
-
+
c = etree.SubElement(root, "Type")
-
+
if service in ("smtp", "imap"):
type = service.upper()
elif service in "pop":
type = "POP3"
-
+ elif service in "caldav":
+ type = "CalDAV"
+ elif service in "carddav":
+ type = "CardDAV"
+ elif service in "ox":
+ type ="X-OX-APPSUITE"
+
c.text = type
if elem.has_key(service + "_server"):
@@ -305,7 +311,7 @@ class View(object):
c = etree.SubElement(root, "Port")
c.text = elem[service + "_port"]
-
+
c = etree.SubElement(root, "DomainRequired")
c.text = "off"
# DomainName - not implemented, yet
@@ -313,7 +319,7 @@ class View(object):
if elem.has_key(service + "_auth_identity"):
c = etree.SubElement(root, "LoginName")
c.text = elem[service + "_auth_identity"]
-
+
if elem.has_key(service + "_auth"):
c = etree.SubElement(root, "SPA")
@@ -324,7 +330,7 @@ class View(object):
spa = "on"
else:
spa = "off"
-
+
c.text = spa
if elem.has_key(service + "_encryption"):
@@ -343,7 +349,7 @@ class View(object):
else:
# anything that we can not understand leads into "None"
ssl = "None"
-
+
c.text = ssl
c = etree.SubElement(root, "AuthRequired")
@@ -380,32 +386,32 @@ class View(object):
sub_root = etree.SubElement(root,
"incomingServer",
type="pop3")
-
+
if elem.has_key(service + "_server"):
c = etree.SubElement(sub_root, "hostname")
c.text = elem[service + "_server"]
-
+
if elem.has_key(service + "_port"):
c = etree.SubElement(sub_root, "port")
c.text = elem[service + "_port"]
-
+
if elem.has_key(service + "_encryption"):
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 elem.has_key(service + "_auth"):
c = etree.SubElement(sub_root, "authentication")
-
+
value = elem[service + "_auth"]
result = ""
-
+
if value == "cleartext":
result = "password-cleartext"
elif value == "encrypted":
@@ -423,46 +429,46 @@ class View(object):
elif value == "smtp-after-pop":
if service == "smtp":
result = "SMTP-after-POP"
-
+
c.text = result
-
+
if elem.has_key(service + "_auth_identity"):
c = etree.SubElement(sub_root, "username")
c.text = elem[service + "_auth_identity"]
-
+
if service == "smtp":
if elem.has_key(service + "_default"):
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 elem.has_key(service + "_server"):
if service in ("imap", "pop"):
proto["in_server"] = elem[service + "_server"]
- else:
+ elif service == "smtp":
proto["out_server"] = elem[service + "_server"]
if elem.has_key(service + "_port"):
if service in ("imap", "pop"):
proto["in_port"] = int(elem[service + "_port"])
- else:
+ elif service == "smtp":
proto["out_port"] = int(elem[service + "_port"])
-
+
if elem.has_key(service + "_auth_identity"):
if service in ("imap", "pop"):
proto["in_username"] = elem[service + "_auth_identity"]
- else:
+ elif service == "smtp":
proto["out_username"] = elem[service + "_auth_identity"]
if elem.has_key(service + "_auth"):
@@ -487,26 +493,26 @@ class View(object):
pass
elif value == "none":
result = "EmailAuthNone"
-
+
if service in ("imap", "pop"):
proto["in_auth"] = result
- else:
+ elif service == "smtp":
proto["out_auth"] = result
-
+
if elem.has_key(service + "_encryption"):
value = elem[service + "_encryption"]
-
+
if value in ("ssl", "starttls"):
if service in ("imap", "pop"):
proto["in_encryption"] = True
- else:
+ elif service == "smtp":
proto["out_encryption"] = True
else:
if service in ("imap", "pop"):
proto["in_encryption"] = False
- else:
+ elif service == "smtp":
proto["out_encryption"] = False
-
+
def render(self):
"""Return the XML result of the view as a character string.
"""
@@ -518,10 +524,10 @@ class View(object):
method="xml",
encoding="utf-8",
pretty_print=True)
-
+
elif self.__plist is not None:
plist_unsigned = writePlistToString(self.__plist)
-
+
if self.__model.domain.has_key("sign_mobileconfig"):
if (self.__model.domain["sign_mobileconfig"] is True and
self.__model.domain.has_key("sign_cert") and
@@ -529,23 +535,23 @@ class View(object):
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)
@@ -553,16 +559,16 @@ class View(object):
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
else:
logging.info("Not signing!")
-
+
return plist_unsigned
else:
return ""