Version = '$Header$';
-__version__ = "Beta 0.95.1"
+__version__ = "Beta 0.98.5"
from Plugins.Plugin import PluginDescriptor
from Components.config import config, ConfigSubsection, ConfigInteger,ConfigYesNo,ConfigText
from Components.Network import Network
from twisted.internet import reactor, defer
-from twisted.web2 import server, channel, static, resource, stream, http_headers, responsecode, http
+from twisted.web2 import server, channel, http
from twisted.web2.auth import digest, basic, wrapper
#from twisted.python import util
-from twisted.python.log import startLogging,discardLogs
+from twisted.python.log import startLogging
from twisted.cred.portal import Portal, IRealm
from twisted.cred import checkers, credentials, error
from zope.interface import Interface, implements
-import webif
-import WebIfConfig
-import os
+from WebIfConfig import WebIfConfigScreen
from WebChilds.Toplevel import Toplevel
+
+from Tools.BoundFunction import boundFunction
+
config.plugins.Webinterface = ConfigSubsection()
config.plugins.Webinterface.enable = ConfigYesNo(default = True)
config.plugins.Webinterface.port = ConfigInteger(80,limits = (1, 65536))
config.plugins.Webinterface.includehdd = ConfigYesNo(default = False)
config.plugins.Webinterface.useauth = ConfigYesNo(default = False) # False, because a std. images hasnt a rootpasswd set and so no login. and a login with a empty pwd makes no sense
-config.plugins.Webinterface.debug = ConfigYesNo(default = False) # False by default, not confgurable in GUI. Edit settingsfile directly if needed
+config.plugins.Webinterface.autowritetimer = ConfigYesNo(default = False)
+config.plugins.Webinterface.loadmovielength = ConfigYesNo(default = False)
config.plugins.Webinterface.version = ConfigText(__version__) # used to make the versioninfo accessible enigma2-wide, not confgurable in GUI.
-
+
"""
set DEBUG to True, if twisted should write logoutput to a file.
with this option enabled, twisted will print all TB to the logfile
use tail -f <file> to view this log
"""
-
+
+# PLEASE DONT ENABLE LOGGING BY DEFAULT (OR COMMIT TO PLUGIN CVS)
+# AND DONT ADD CONFIG OPTIONS WHICH HELPS NORMAL USERS TO ENABLE
+# THIS KIND OF LOGGING !!!!!!!!!!!!!
+# Twisted logging can't handle UTF8 correct,
+# and enigma2 internal completely use UTF8 (for debug messages too)
+# so the twisted logging code self generates frequently blue screens
+# at various places in enigma2(not only in Webif) and the reason
+# of this crashes is NOT visible in the normal enigma2 crashlogs
+# We have spent much time into debugging this Ghost 2007/11/15
+
+DEBUG_TO_FILE=False
DEBUGFILE= "/tmp/twisted.log"
-def stopWebserver():
- reactor.disconnectAll()
+global running_defered,waiting_shutdown
+running_defered = []
+waiting_shutdown = 0
+class Closer:
+ counter = 0
+ def __init__(self,session, callback):
+ self.callback = callback
+ self.session = session
+
+ def stop(self):
+ global running_defered
+ for d in running_defered:
+ print "[WebIf] STOPPING reactor on interface ",d.interface," with port",d.port
+ x = d.stopListening()
+ try:
+ x.addCallback(self.isDown)
+ self.counter +=1
+ except AttributeError:
+ pass
+ running_defered = []
+ if self.counter <1:
+ self.callback(self.session)
+
+ def isDown(self,s):
+ self.counter-=1
+ if self.counter <1:
+ self.callback(self.session)
+
+
def restartWebserver(session):
- stopWebserver()
- startWebserver(session)
+ try:
+ del session.mediaplayer
+ del session.messageboxanswer
+ except NameError:
+ pass
+ except AttributeError:
+ pass
-def startWebserver(session):
- if config.plugins.Webinterface.enable.value is not True:
- print "not starting Werbinterface"
- return False
- if config.plugins.Webinterface.debug.value:
- print "start twisted logfile, writing to %s" % DEBUGFILE
- import sys
- startLogging(open(DEBUGFILE,'w'))
-
- toplevel = Toplevel(session)
- if config.plugins.Webinterface.useauth.value is False:
- site = server.Site(toplevel)
+ global running_defered
+ if len(running_defered) >0:
+ Closer(session,startWebserver).stop()
else:
- portal = Portal(HTTPAuthRealm())
- portal.registerChecker(PasswordDatabase())
- root = ModifiedHTTPAuthResource(toplevel,(basic.BasicCredentialFactory('DM7025'),),portal, (IHTTPUser,))
- site = server.Site(root)
-
- # here we start the Toplevel without any username or password
- # this allows access to all request over the iface 127.0.0.1 without any auth
- localsite = server.Site(toplevel)
- reactor.listenTCP(config.plugins.Webinterface.port.value, channel.HTTPFactory(localsite),interface='127.0.0.1')
+ startWebserver(session)
+
+def startWebserver(session):
+ global running_defered
+ try:
+ # variables, that are needed in the process
+ session.mediaplayer = None
+ session.messageboxanswer = None
+
+ 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'))
- # and here we make the Toplevel public to our external ifaces
- # it depends on the config, if this is with auth support
- # keep in mind, if we have a second external ip (like a wlan device), we have to do it in the same way for this iface too
- nw = Network()
- for adaptername in nw.ifaces:
- extip = nw.ifaces[adaptername]['ip']
- if nw.ifaces[adaptername]['up'] is True:
- extip = "%i.%i.%i.%i"%(extip[0],extip[1],extip[2],extip[3])
- print "[WebIf] starting Webinterface on port %s on interface %s with address %s"%(str(config.plugins.Webinterface.port.value),adaptername,extip)
- try:
- reactor.listenTCP(config.plugins.Webinterface.port.value, channel.HTTPFactory(site),interface=extip)
- except Exception,e:
- print "[WebIf] Error starting Webinterface on port %s on interface %s with address %s,because \n%s"%(str(config.plugins.Webinterface.port.value),adaptername,extip,e)
+ toplevel = Toplevel(session)
+ if config.plugins.Webinterface.useauth.value is False:
+ site = server.Site(toplevel)
else:
- print "[WebIf] found configured interface %s, but it is not running. so not starting a server on it ..." % adaptername
-
+ portal = Portal(HTTPAuthRealm())
+ portal.registerChecker(PasswordDatabase())
+ root = ModifiedHTTPAuthResource(toplevel,(basic.BasicCredentialFactory('DM7025'),),portal, (IHTTPUser,))
+ site = server.Site(root)
+
+ # here we start the Toplevel without any username or password
+ # this allows access to all request over the iface 127.0.0.1 without any auth
+ localsite = server.Site(toplevel)
+ d = reactor.listenTCP(config.plugins.Webinterface.port.value, channel.HTTPFactory(localsite),interface='127.0.0.1')
+ running_defered.append(d)
+ # and here we make the Toplevel public to our external ifaces
+ # it depends on the config, if this is with auth support
+ # keep in mind, if we have a second external ip (like a wlan device), we have to do it in the same way for this iface too
+ nw = Network()
+ for adaptername in nw.ifaces:
+ extip = nw.ifaces[adaptername]['ip']
+ if nw.ifaces[adaptername]['up'] is True:
+ extip = "%i.%i.%i.%i"%(extip[0],extip[1],extip[2],extip[3])
+ print "[WebIf] starting Webinterface on port %s on interface %s with address %s"%(str(config.plugins.Webinterface.port.value),adaptername,extip)
+ try:
+ d = reactor.listenTCP(config.plugins.Webinterface.port.value, channel.HTTPFactory(site),interface=extip)
+ running_defered.append(d)
+ except Exception,e:
+ print "[WebIf] Error starting Webinterface on port %s on interface %s with address %s,because \n%s"%(str(config.plugins.Webinterface.port.value),adaptername,extip,e)
+ else:
+ print "[WebIf] found configured interface %s, but it is not running. so not starting a server on it ..." % adaptername
+ except Exception,e:
+ print "\n\nSomething went wrong on starting the webif. May the following Line can help to find the error:\n",e,"\n\n"
####
def autostart(reason, **kwargs):
if "session" in kwargs:
print "[WebIf] twisted not available, not starting web services",e
def openconfig(session, **kwargs):
- session.openWithCallback(configCB,WebIfConfig.WebIfConfigScreen)
+ session.openWithCallback(configCB,WebIfConfigScreen)
def configCB(result,session):
if result is True:
return IHTTPUser, HTTPUser()
raise NotImplementedError("Only IHTTPUser interface is supported")
-
-import md5,time,string,crypt
+
+from string import find, split
+from md5 import new as md5_new
+from crypt import crypt
+
DES_SALT = list('./0123456789' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz')
def getpwnam(name, pwfile=None):
"""Return pasword database entry for the given user name.
def passcrypt(passwd, salt=None, method='des', magic='$1$'):
"""Encrypt a string according to rules in crypt(3)."""
if method.lower() == 'des':
- return crypt.crypt(passwd, salt)
+ return crypt(passwd, salt)
elif method.lower() == 'md5':
return passcrypt_md5(passwd, salt, magic)
elif method.lower() == 'clear':
if not enc_passwd:
return 0
elif len(enc_passwd) >= 3 and enc_passwd[:3] == '$1$':
- salt = enc_passwd[3:string.find(enc_passwd, '$', 3)]
+ salt = enc_passwd[3:find(enc_passwd, '$', 3)]
return enc_passwd == passcrypt(passwd, salt, 'md5')
else:
salt = salt[len(magic):]
# salt only goes up to first '$'
- salt = string.split(salt, '$')[0]
+ salt = split(salt, '$')[0]
# limit length of salt to 8
salt = salt[:8]
- ctx = md5.new(passwd)
+ ctx = md5_new(passwd)
ctx.update(magic)
ctx.update(salt)
- ctx1 = md5.new(passwd)
+ ctx1 = md5_new(passwd)
ctx1.update(salt)
ctx1.update(passwd)
final = ctx.digest()
for i in range(1000):
- ctx1 = md5.new()
+ ctx1 = md5_new()
if i & 1:
ctx1.update(passwd)
else: