X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=webinterface%2Fsrc%2Fplugin.py;h=17d61f8b8fdfd7eb79f5b3205db6f390cef05781;hb=e108b6d4d922debab92bbf0cfa7113fd7638d54f;hp=e05aebf0c6e4de5236bb0f550e4a53ece3a1f2c7;hpb=2f166c0090c5e7ad585fdff636b3b288f962ba4b;p=vuplus_dvbapp-plugin diff --git a/webinterface/src/plugin.py b/webinterface/src/plugin.py index e05aebf..17d61f8 100644 --- a/webinterface/src/plugin.py +++ b/webinterface/src/plugin.py @@ -1,52 +1,143 @@ Version = '$Header$'; + +from enigma import eConsoleAppContainer, eTPM from Plugins.Plugin import PluginDescriptor -from Components.config import config + +from Components.config import config, ConfigBoolean, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText +from Components.Network import iNetwork from Screens.MessageBox import MessageBox from WebIfConfig import WebIfConfigScreen -from WebChilds.Toplevel import Toplevel -from twisted.internet import reactor, defer -from twisted.web2 import server, channel, http -from twisted.web2.auth import digest, basic, wrapper -from twisted.python.log import startLogging -from twisted.cred.portal import Portal, IRealm -from twisted.cred import checkers, credentials, error +from WebChilds.Toplevel import getToplevel +from Tools.HardwareInfo import HardwareInfo + +from Tools.Directories import copyfile, resolveFilename, SCOPE_PLUGINS, SCOPE_CONFIG + +from twisted.internet import reactor, ssl +from twisted.web import server, http, util, static, resource + from zope.interface import Interface, implements from socket import gethostname as socket_gethostname -DEBUG_TO_FILE=False # PLEASE DONT ENABLE LOGGING BY DEFAULT (OR COMMIT TO PLUGIN CVS) +from OpenSSL import SSL + +from os.path import isfile as os_isfile +from __init__ import _, __version__, decrypt_block +from webif import get_random, validate_certificate + +tpm = eTPM() +rootkey = ['\x9f', '|', '\xe4', 'G', '\xc9', '\xb4', '\xf4', '#', '&', '\xce', '\xb3', '\xfe', '\xda', '\xc9', 'U', '`', '\xd8', '\x8c', 's', 'o', '\x90', '\x9b', '\\', 'b', '\xc0', '\x89', '\xd1', '\x8c', '\x9e', 'J', 'T', '\xc5', 'X', '\xa1', '\xb8', '\x13', '5', 'E', '\x02', '\xc9', '\xb2', '\xe6', 't', '\x89', '\xde', '\xcd', '\x9d', '\x11', '\xdd', '\xc7', '\xf4', '\xe4', '\xe4', '\xbc', '\xdb', '\x9c', '\xea', '}', '\xad', '\xda', 't', 'r', '\x9b', '\xdc', '\xbc', '\x18', '3', '\xe7', '\xaf', '|', '\xae', '\x0c', '\xe3', '\xb5', '\x84', '\x8d', '\r', '\x8d', '\x9d', '2', '\xd0', '\xce', '\xd5', 'q', '\t', '\x84', 'c', '\xa8', ')', '\x99', '\xdc', '<', '"', 'x', '\xe8', '\x87', '\x8f', '\x02', ';', 'S', 'm', '\xd5', '\xf0', '\xa3', '_', '\xb7', 'T', '\t', '\xde', '\xa7', '\xf1', '\xc9', '\xae', '\x8a', '\xd7', '\xd2', '\xcf', '\xb2', '.', '\x13', '\xfb', '\xac', 'j', '\xdf', '\xb1', '\x1d', ':', '?'] +hw = HardwareInfo() +#CONFIG INIT -DEBUGFILE= "/tmp/twisted.log" +#init the config +config.plugins.Webinterface = ConfigSubsection() +config.plugins.Webinterface.enabled = ConfigYesNo(default=True) +config.plugins.Webinterface.allowzapping = ConfigYesNo(default=True) +config.plugins.Webinterface.includemedia = ConfigYesNo(default=False) +config.plugins.Webinterface.autowritetimer = ConfigYesNo(default=False) +config.plugins.Webinterface.loadmovielength = ConfigYesNo(default=True) +config.plugins.Webinterface.version = ConfigText(__version__) # used to make the versioninfo accessible enigma2-wide, not confgurable in GUI. + +config.plugins.Webinterface.http = ConfigSubsection() +config.plugins.Webinterface.http.enabled = ConfigYesNo(default=True) +config.plugins.Webinterface.http.port = ConfigInteger(default = 80, limits=(1, 65535) ) +config.plugins.Webinterface.http.auth = ConfigYesNo(default=False) + +config.plugins.Webinterface.https = ConfigSubsection() +config.plugins.Webinterface.https.enabled = ConfigYesNo(default=True) +config.plugins.Webinterface.https.port = ConfigInteger(default = 443, limits=(1, 65535) ) +config.plugins.Webinterface.https.auth = ConfigYesNo(default=True) + +config.plugins.Webinterface.streamauth = ConfigYesNo(default=False) + +global running_defered, waiting_shutdown, toplevel -global running_defered,waiting_shutdown running_defered = [] waiting_shutdown = 0 +toplevel = None +server.VERSION = "Enigma2 WebInterface Server $Revision$".replace("$Revi", "").replace("sion: ", "").replace("$", "") +#=============================================================================== +# Helperclass to close running Instances of the Webinterface +#=============================================================================== class Closer: counter = 0 - def __init__(self,session, callback): + def __init__(self, session, callback=None, l2k=None): self.callback = callback self.session = session - + self.l2k = l2k +#=============================================================================== +# Closes all running Instances of the Webinterface +#=============================================================================== def stop(self): global running_defered for d in running_defered: - print "[Webinterface] stopping interface on ",d.interface," with port",d.port + print "[Webinterface] stopping interface on ", d.interface, " with port", d.port x = d.stopListening() + try: x.addCallback(self.isDown) - self.counter +=1 + self.counter += 1 except AttributeError: pass running_defered = [] - if self.counter <1: - self.callback(self.session) + if self.counter < 1: + if self.callback is not None: + self.callback(self.session, self.l2k) + +#=============================================================================== +# #Is it already down? +#=============================================================================== + def isDown(self, s): + self.counter -= 1 + if self.counter < 1: + if self.callback is not None: + self.callback(self.session, self.l2k) + +def checkCertificates(): + print "[WebInterface] checking for SSL Certificates" + srvcert = '%sserver.pem' %resolveFilename(SCOPE_CONFIG) + cacert = '%scacert.pem' %resolveFilename(SCOPE_CONFIG) + + # Check whether there are regular certificates, if not copy the default ones over + if not os_isfile(srvcert) or not os_isfile(cacert): + return False + + else: + return True - def isDown(self,s): - self.counter-=1 - if self.counter <1: - self.callback(self.session) - +def installCertificates(session, callback = None, l2k = None): + print "[WebInterface] Installing SSL Certificates to %s" %resolveFilename(SCOPE_CONFIG) + + srvcert = '%sserver.pem' %resolveFilename(SCOPE_CONFIG) + cacert = '%scacert.pem' %resolveFilename(SCOPE_CONFIG) + scope_webif = '%sExtensions/WebInterface/' %resolveFilename(SCOPE_PLUGINS) + + source = '%setc/server.pem' %scope_webif + target = srvcert + ret = copyfile(source, target) + + if ret == 0: + source = '%setc/cacert.pem' %scope_webif + target = cacert + ret = copyfile(source, target) + + if ret == 0 and callback != None: + callback(session, l2k) + + if ret < 0: + config.plugins.Webinterface.https.enabled.value = False + config.plugins.Webinterface.https.enabled.save() + + # Start without https + callback(session, l2k) -def restartWebserver(session): + #Inform the user + session.open(MessageBox, "Couldn't install SSL-Certifactes for https access\nHttps access is now disabled!", MessageBox.TYPE_ERROR) + +#=============================================================================== +# restart the Webinterface for all configured Interfaces +#=============================================================================== +def restartWebserver(session, l2k): try: del session.mediaplayer del session.messageboxanswer @@ -56,245 +147,342 @@ def restartWebserver(session): pass global running_defered - if len(running_defered) >0: - Closer(session,startWebserver).stop() + if len(running_defered) > 0: + Closer(session, startWebserver, l2k).stop() else: - startWebserver(session) - -def startWebserver(session): + startWebserver(session, l2k) + +#=============================================================================== +# start the Webinterface for all configured Interfaces +#=============================================================================== +def startWebserver(session, l2k): global running_defered + global toplevel + session.mediaplayer = None session.messageboxanswer = None + if toplevel is None: + toplevel = getToplevel(session) - if config.plugins.Webinterface.enable.value is not True: - print "not starting Werbinterface" - return False - if DEBUG_TO_FILE: - print "start twisted logfile, writing to %s" % DEBUGFILE - startLogging(open(DEBUGFILE,'w')) + errors = "" - for i in range(0, config.plugins.Webinterface.interfacecount.value): - c = config.plugins.Webinterface.interfaces[i] - if c.disabled.value is False: - startServerInstance(session,c.adress.value,c.port.value,c.useauth.value) - else: - print "[Webinterface] not starting disabled interface on %s:%i"%(c.adress.value,c.port.value) + if config.plugins.Webinterface.enabled.value is not True: + print "[Webinterface] is disabled!" + + else: + # IF SSL is enabled we need to check for the certs first + # If they're not there we'll exit via return here + # and get called after Certificates are installed properly + if config.plugins.Webinterface.https.enabled.value: + if not checkCertificates(): + print "[Webinterface] Installing Webserver Certificates for SSL encryption" + installCertificates(session, startWebserver, l2k) + return + # Listen on all Interfaces + ip = "0.0.0.0" + #HTTP + if config.plugins.Webinterface.http.enabled.value is True: + ret = startServerInstance(session, ip, config.plugins.Webinterface.http.port.value, config.plugins.Webinterface.http.auth.value, l2k) + if ret == False: + errors = "%s%s:%i\n" %(errors, ip, config.plugins.Webinterface.http.port.value) + else: + registerBonjourService('http', config.plugins.Webinterface.http.port.value) -def startServerInstance(session,ipadress,port,useauth=False): - try: - toplevel = Toplevel(session) - if useauth: - portal = Portal(HTTPAuthRealm()) - portal.registerChecker(PasswordDatabase()) - root = ModifiedHTTPAuthResource(toplevel,(basic.BasicCredentialFactory(socket_gethostname()),),portal, (IHTTPUser,)) - site = server.Site(root) - else: - site = server.Site(toplevel) - d = reactor.listenTCP(port, channel.HTTPFactory(site),interface=ipadress) - running_defered.append(d) - print "[Webinterface] started on %s:%i"%(ipadress,port),"auth=",useauth - except Exception,e: - print "[Webinterface] starting FAILED on %s:%i!"%(ipadress,port),e - session.open(MessageBox,'starting FAILED on %s:%i!\n\n%s'%(ipadress,port,str(e)), MessageBox.TYPE_ERROR) - -def autostart(reason, **kwargs): - if "session" in kwargs: - try: - startWebserver(kwargs["session"]) - except ImportError,e: - print "[Webinterface] twisted not available, not starting web services",e + #Streaming requires listening on 127.0.0.1:80 no matter what, ensure it its available + if config.plugins.Webinterface.http.port.value != 80 or not config.plugins.Webinterface.http.enabled.value: + #LOCAL HTTP Connections (Streamproxy) + ret = startServerInstance(session, '127.0.0.1', 80, config.plugins.Webinterface.http.auth.value, l2k) + if ret == False: + errors = "%s%s:%i\n" %(errors, '127.0.0.1', 80) -def openconfig(session, **kwargs): - session.openWithCallback(configCB,WebIfConfigScreen) + if errors != "": + session.open(MessageBox, "Webinterface - Couldn't listen on:\n %s" % (errors), type=MessageBox.TYPE_ERROR, timeout=30) + + #HTTPS + if config.plugins.Webinterface.https.enabled.value is True: + ret = startServerInstance(session, ip, config.plugins.Webinterface.https.port.value, config.plugins.Webinterface.https.auth.value, l2k, True) + if ret == False: + errors = "%s%s:%i\n" %(errors, ip, config.plugins.Webinterface.https.port.value) + else: + registerBonjourService('https', config.plugins.Webinterface.https.port.value) + +#=============================================================================== +# stop the Webinterface for all configured Interfaces +#=============================================================================== +def stopWebserver(session): + try: + del session.mediaplayer + del session.messageboxanswer + except NameError: + pass + except AttributeError: + pass -def configCB(result,session): - if result is True: - print "[WebIf] config changed" - restartWebserver(session) - else: - print "[WebIf] config not changed" + global running_defered + if len(running_defered) > 0: + Closer(session).stop() + +#=============================================================================== +# startServerInstance +# Starts an Instance of the Webinterface +# on given ipaddress, port, w/o auth, w/o ssl +#=============================================================================== +def startServerInstance(session, ipaddress, port, useauth=False, l2k=None, usessl=False): + if hw.get_device_name().lower() != "dm7025": + l3k = None + l3c = tpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT) + + if l3c is None: + return False + + l3k = validate_certificate(l3c, l2k) + if l3k is None: + return False + + random = get_random() + if random is None: + return False + + value = tpm.challenge(random) + result = decrypt_block(value, l3k) + + if result is None: + return False + else: + if result [80:88] != random: + return False + if useauth: +# HTTPAuthResource handles the authentication for every Resource you want it to + root = HTTPAuthResource(toplevel, "Enigma2 WebInterface") + site = server.Site(root) + else: + site = server.Site(toplevel) -def Plugins(**kwargs): - return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart), - PluginDescriptor(name=_("Webinterface"), description=_("Configuration for the Webinterface"),where = [PluginDescriptor.WHERE_PLUGINMENU], icon="plugin.png",fnc = openconfig)] + if usessl: + + ctx = ssl.DefaultOpenSSLContextFactory('/etc/enigma2/server.pem', '/etc/enigma2/cacert.pem', sslmethod=SSL.SSLv23_METHOD) + d = reactor.listenSSL(port, site, ctx, interface=ipaddress) + else: + d = reactor.listenTCP(port, site, interface=ipaddress) + running_defered.append(d) + print "[Webinterface] started on %s:%i auth=%s ssl=%s" % (ipaddress, port, useauth, usessl) + return True + #except Exception, e: + #print "[Webinterface] starting FAILED on %s:%i!" % (ipaddress, port), e + #return False +#=============================================================================== +# HTTPAuthResource +# Handles HTTP Authorization for a given Resource +#=============================================================================== +class HTTPAuthResource(resource.Resource): + def __init__(self, res, realm): + resource.Resource.__init__(self) + self.resource = res + self.realm = realm + self.authorized = False + self.tries = 0 + self.unauthorizedResource = UnauthorizedResource(self.realm) -class ModifiedHTTPAuthResource(wrapper.HTTPAuthResource): - """ - set it only to True, if you have a patched wrapper.py - see http://twistedmatrix.com/trac/ticket/2041 - so, the solution for us is to make a new class an override ne faulty func - """ - - def locateChild(self, req, seg): - return self.authenticate(req), seg + def unautorized(self, request): + request.setResponseCode(http.UNAUTHORIZED) + request.setHeader('WWW-authenticate', 'basic realm="%s"' % self.realm) + + return self.unauthorizedResource -class PasswordDatabase: - """ - this checks webiflogins agains /etc/passwd - """ - passwordfile = "/etc/passwd" - implements(checkers.ICredentialsChecker) - credentialInterfaces = (credentials.IUsernamePassword,credentials.IUsernameHashedPassword) - - def _cbPasswordMatch(self, matched, username): - if matched: - return username - else: - return failure.Failure(error.UnauthorizedLogin()) - - def requestAvatarId(self, credentials): - if check_passwd(credentials.username,credentials.password,self.passwordfile) is True: - return defer.maybeDeferred(credentials.checkPassword,credentials.password).addCallback(self._cbPasswordMatch, str(credentials.username)) - else: - return defer.fail(error.UnauthorizedLogin()) - -class IHTTPUser(Interface): - pass - -class HTTPUser(object): - implements(IHTTPUser) - -class HTTPAuthRealm(object): - implements(IRealm) - def requestAvatar(self, avatarId, mind, *interfaces): - if IHTTPUser in interfaces: - return IHTTPUser, HTTPUser() - raise NotImplementedError("Only IHTTPUser interface is supported") - - -from string import find, split -from md5 import new as md5_new + def isAuthenticated(self, request): + host = request.getHost().host + #If streamauth is disabled allow all acces from localhost + if not config.plugins.Webinterface.streamauth.value: + if( host == "127.0.0.1" or host == "localhost" ): + print "[WebInterface.plugin.isAuthenticated] Streaming auth is disabled bypassing authcheck because host is '%s'" %host + return True + + # get the Session from the Request + sessionNs = request.getSession().sessionNamespaces + + # if the auth-information has not yet been stored to the session + if not sessionNs.has_key('authenticated'): + if request.getUser() != '': + sessionNs['authenticated'] = check_passwd(request.getUser(), request.getPassword()) + else: + sessionNs['authenticated'] = False + + #if the auth-information already is in the session + else: + if sessionNs['authenticated'] is False: + sessionNs['authenticated'] = check_passwd(request.getUser(), request.getPassword() ) + + #return the current authentication status + return sessionNs['authenticated'] + +#=============================================================================== +# Call render of self.resource (if authenticated) +#=============================================================================== + def render(self, request): + if self.isAuthenticated(request) is True: + return self.resource.render(request) + + else: + print "[Webinterface.HTTPAuthResource.render] !!! unauthorized !!!" + return self.unautorized(request).render(request) + +#=============================================================================== +# Override to call getChildWithDefault of self.resource (if authenticated) +#=============================================================================== + def getChildWithDefault(self, path, request): + if self.isAuthenticated(request) is True: + return self.resource.getChildWithDefault(path, request) + + else: + print "[Webinterface.HTTPAuthResource.render] !!! unauthorized !!!" + return self.unautorized(request) + +#=============================================================================== +# UnauthorizedResource +# Returns a simple html-ified "Access Denied" +#=============================================================================== +class UnauthorizedResource(resource.Resource): + def __init__(self, realm): + resource.Resource.__init__(self) + self.realm = realm + self.errorpage = static.Data('Access Denied.', 'text/html') + + def getChild(self, path, request): + return self.errorpage + + def render(self, request): + return self.errorpage.render(request) + + + +# Password verfication stuff from crypt import crypt +from pwd import getpwnam +from spwd import getspnam + + +def check_passwd(name, passwd): + cryptedpass = None + try: + cryptedpass = getpwnam(name)[1] + except: + return False + + if cryptedpass: + #shadowed or not, that's the questions here + if cryptedpass == 'x' or cryptedpass == '*': + try: + cryptedpass = getspnam(name)[1] + except: + return False + + return crypt(passwd, cryptedpass) == cryptedpass + return False + +global_session = None -DES_SALT = list('./0123456789' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz') -def getpwnam(name, pwfile=None): - """Return pasword database entry for the given user name. - - Example from the Python Library Reference. - """ - - if not pwfile: - pwfile = '/etc/passwd' - - f = open(pwfile) - while 1: - line = f.readline() - if not line: - f.close() - raise KeyError, name - entry = tuple(line.strip().split(':', 6)) - if entry[0] == name: - f.close() - return entry - -def passcrypt(passwd, salt=None, method='des', magic='$1$'): - """Encrypt a string according to rules in crypt(3).""" - if method.lower() == 'des': - return crypt(passwd, salt) - elif method.lower() == 'md5': - return passcrypt_md5(passwd, salt, magic) - elif method.lower() == 'clear': - return passwd - -def check_passwd(name, passwd, pwfile=None): - """Validate given user, passwd pair against password database.""" - - if not pwfile or type(pwfile) == type(''): - getuser = lambda x,pwfile=pwfile: getpwnam(x,pwfile)[1] - else: - getuser = pwfile.get_passwd - - try: - enc_passwd = getuser(name) - except (KeyError, IOError): - return 0 - if not enc_passwd: - return 0 - elif len(enc_passwd) >= 3 and enc_passwd[:3] == '$1$': - salt = enc_passwd[3:find(enc_passwd, '$', 3)] - return enc_passwd == passcrypt(passwd, salt, 'md5') - - else: - return enc_passwd == passcrypt(passwd, enc_passwd[:2]) - -def _to64(v, n): - r = '' - while (n-1 >= 0): - r = r + DES_SALT[v & 0x3F] - v = v >> 6 - n = n - 1 - return r +#=============================================================================== +# sessionstart +# Actions to take place on Session start +#=============================================================================== +def sessionstart(reason, session): + global global_session + global_session = session + + +def registerBonjourService(protocol, port): + try: + from Plugins.Extensions.Bonjour.Bonjour import bonjour + + service = bonjour.buildService(protocol, port) + bonjour.registerService(service, True) + print "[WebInterface.registerBonjourService] Service for protocol '%s' with port '%i' registered!" %(protocol, port) + return True + + except ImportError, e: + print "[WebInterface.registerBonjourService] %s" %e + return False + +def unregisterBonjourService(protocol): + try: + from Plugins.Extensions.Bonjour.Bonjour import bonjour + + bonjour.unregisterService(protocol) + print "[WebInterface.unregisterBonjourService] Service for protocol '%s' unregistered!" %(protocol) + return True + + except ImportError, e: + print "[WebInterface.unregisterBonjourService] %s" %e + return False + +def checkBonjour(): + if ( not config.plugins.Webinterface.http.enabled.value ) or ( not config.plugins.Webinterface.enabled.value ): + unregisterBonjourService('http') + if ( not config.plugins.Webinterface.https.enabled.value ) or ( not config.plugins.Webinterface.enabled.value ): + unregisterBonjourService('https') + +#=============================================================================== +# networkstart +# Actions to take place after Network is up (startup the Webserver) +#=============================================================================== +def networkstart(reason, **kwargs): + l2r = False + l2k = None + if hw.get_device_name().lower() != "dm7025": + l2c = tpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT) + + if l2c is None: + return + + l2k = validate_certificate(l2c, rootkey) + if l2k is None: + return -def passcrypt_md5(passwd, salt=None, magic='$1$'): - """Encrypt passwd with MD5 algorithm.""" - - if not salt: - pass - elif salt[:len(magic)] == magic: - # remove magic from salt if present - salt = salt[len(magic):] - - # salt only goes up to first '$' - salt = split(salt, '$')[0] - # limit length of salt to 8 - salt = salt[:8] - - ctx = md5_new(passwd) - ctx.update(magic) - ctx.update(salt) - - ctx1 = md5_new(passwd) - ctx1.update(salt) - ctx1.update(passwd) - - final = ctx1.digest() - - for i in range(len(passwd), 0 , -16): - if i > 16: - ctx.update(final) - else: - ctx.update(final[:i]) - - i = len(passwd) - while i: - if i & 1: - ctx.update('\0') + l2r = True else: - ctx.update(passwd[:1]) - i = i >> 1 - final = ctx.digest() - - for i in range(1000): - ctx1 = md5_new() - if i & 1: - ctx1.update(passwd) - else: - ctx1.update(final) - if i % 3: ctx1.update(salt) - if i % 7: ctx1.update(passwd) - if i & 1: - ctx1.update(final) - else: - ctx1.update(passwd) - final = ctx1.digest() - - rv = magic + salt + '$' - final = map(ord, final) - l = (final[0] << 16) + (final[6] << 8) + final[12] - rv = rv + _to64(l, 4) - l = (final[1] << 16) + (final[7] << 8) + final[13] - rv = rv + _to64(l, 4) - l = (final[2] << 16) + (final[8] << 8) + final[14] - rv = rv + _to64(l, 4) - l = (final[3] << 16) + (final[9] << 8) + final[15] - rv = rv + _to64(l, 4) - l = (final[4] << 16) + (final[10] << 8) + final[5] - rv = rv + _to64(l, 4) - l = final[11] - rv = rv + _to64(l, 2) - - return rv + l2r = True + + if l2r: + if reason is True: + startWebserver(global_session, l2k) + checkBonjour() + + elif reason is False: + stopWebserver(global_session) + checkBonjour() + +def openconfig(session, **kwargs): + session.openWithCallback(configCB, WebIfConfigScreen) +def configCB(result, session): + l2r = False + l2k = None + if hw.get_device_name().lower() != "dm7025": + l2c = tpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT) + + if l2c is None: + return + + l2k = validate_certificate(l2c, rootkey) + if l2k is None: + return + + l2r = True + else: + l2r = True + + if l2r: + if result: + print "[WebIf] config changed" + restartWebserver(session, l2k) + checkBonjour() + else: + print "[WebIf] config not changed" +def Plugins(**kwargs): + return [PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=sessionstart), + PluginDescriptor(where=[PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc=networkstart), + PluginDescriptor(name=_("Webinterface"), description=_("Configuration for the Webinterface"), + where=[PluginDescriptor.WHERE_PLUGINMENU], icon="plugin.png", fnc=openconfig)]