diff --git a/pythonrewrite/bin2/CryptoBox.py b/pythonrewrite/bin2/CryptoBox.py index 5a8d176..f5885a5 100755 --- a/pythonrewrite/bin2/CryptoBox.py +++ b/pythonrewrite/bin2/CryptoBox.py @@ -262,6 +262,16 @@ class CryptoBoxProps(CryptoBox): return [] + def getContainer(self, device): + "retrieve the container element for this device" + all = [e for e in self.getContainerList() if e.device == device] + if all: + return all[0] + else: + return None + + + def setNameForUUID(self, uuid, name): "assign a name to a uuid in the ContainerNameDatabase" used_uuid = self.getUUIDForName(name) diff --git a/pythonrewrite/bin2/CryptoBoxContainer.py b/pythonrewrite/bin2/CryptoBoxContainer.py index e446779..1bed389 100755 --- a/pythonrewrite/bin2/CryptoBoxContainer.py +++ b/pythonrewrite/bin2/CryptoBoxContainer.py @@ -508,7 +508,7 @@ class CryptoBoxContainer: "luksFormat", self.device, "--batch-mode", - "--cipher", self.cbox.cbxPrefs["System"]["DefaultCipher"], + "--cipher", self.cbox.cbxPrefs["Main"]["DefaultCipher"], "--iter-time", "2000"]) proc.stdin.write(password) (output, errout) = proc.communicate() diff --git a/pythonrewrite/bin2/CryptoBoxWebserver.py b/pythonrewrite/bin2/CryptoBoxWebserver.py index d8f0df4..aa2e854 100755 --- a/pythonrewrite/bin2/CryptoBoxWebserver.py +++ b/pythonrewrite/bin2/CryptoBoxWebserver.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2.4 import os -import CryptoBoxWebserverSites +import WebInterfaceSites try: import cherrypy @@ -12,7 +12,7 @@ class CryptoBoxWebserver: '''this class starts the cherryp webserver and serves the single sites''' def __init__(self): - cherrypy.root = CryptoBoxWebserverSites.CryptoBoxWebserverSites() + cherrypy.root = WebInterfaceSites.WebInterfaceSites() #expose static content: #I currently have no idea how to cleanly extract the stylesheet path from #the config object without an extra CryptoBox.CryptoBoxProps instance. diff --git a/pythonrewrite/bin2/CryptoBoxWebserverRender.py b/pythonrewrite/bin2/CryptoBoxWebserverRender.py deleted file mode 100644 index a2b1b4e..0000000 --- a/pythonrewrite/bin2/CryptoBoxWebserverRender.py +++ /dev/null @@ -1,42 +0,0 @@ -import os -try: - import neo_cgi, neo_util, neo_cs -except ImportError: - raise ImportError("could not import clearsilver modules! Try apt-get install python-clearsilver.") - -class CryptoBoxWebserverRender: - '''renders the site with clearsilver template and languagefile - - ''' - def render(self, website): - '''renders from clearsilver templates and returns the resulting html - - Gets a dictionary with all settings, nessessary for rendering. - In fact the dictionary is a copy of the CryptoBoxWerbserverSite - object, that calls this render method. This might be bloat but - this way the render method has always a complete, actual set of values. - ''' - - website.log.info("rendering site: "+website.settings["Data.Action"]) - - cs_path = website.cbxPrefs["Locations"]["TemplateDir"]+"/main.cs" - if not os.access(cs_path, os.R_OK): - website.log.error("Couldn't read cs file: %s" % cs_path) - return "Couldn't read cs file: %s" % cs_path - - #hdf_path = website.cbxPrefs["Locations"]["LangDir"]+"/"+website.cbxPrefs["WebSettings"]["Language"]+".hdf" - # use the user selected language ('Settings.Language') instead of the configured - hdf_path = website.cbxPrefs["Locations"]["LangDir"]+"/"+website.settings["Settings.Language"]+".hdf" - if not os.access(hdf_path, os.R_OK): - website.log.error("Couldn't read hdf file: %s" % hdf_path) - return "Couldn't read hdf file: %s" % hdf_path - - hdf = neo_util.HDF() - hdf.readFile(hdf_path) - website.log.debug(website.settings) - for key in website.settings.keys(): - hdf.setValue(key,str(website.settings[key])) - cs = neo_cs.CS(hdf) - cs.parseFile(cs_path) - return cs.render() - diff --git a/pythonrewrite/bin2/CryptoBoxWebserverSettings.py b/pythonrewrite/bin2/CryptoBoxWebserverSettings.py deleted file mode 100644 index 0bfb561..0000000 --- a/pythonrewrite/bin2/CryptoBoxWebserverSettings.py +++ /dev/null @@ -1,42 +0,0 @@ -class CryptoBoxWebserverSettings: - '''this is the motherclass of all cbx site settings - - put the stuff in here, that every site will need access to''' - - def setSettings(self, website): - '''fills a dictionary with values from the configfile - - There may also be set some useful standards here.''' - website.settings={} - #TODO: this is nessessary since the last config split in different sections - ## put all found WebSettings values in the dictionary - ## RFC: arbitrarily importing all available keys does not sound very secure [l] - ## RFC: settings with the same names in different sections (Log, Main, ...) will collide silently - right? [l] - ## yep, we'll have to divide between settings for clearsilver and settings we need for other webstuff [a] - ## I think it would be better to expose only the necessary settings (manually - not just everything) [l] - for key in self.cbxPrefs["WebSettings"].keys(): - website.settings["Settings."+key] = self.cbxPrefs["WebSettings"][key] - ## also all Log values - for key in self.cbxPrefs["Log"].keys(): - website.settings["Log."+key] = self.cbxPrefs["Log"][key] - ## also Main - for key in self.cbxPrefs["Main"].keys(): - website.settings["Settings."+key] = self.cbxPrefs["Main"][key] - ## Locations dito - for key in self.cbxPrefs["Locations"].keys(): - website.settings["Settings."+key] = self.cbxPrefs["Locations"][key] - - ## put available languages also in the dictionary - website.settings["Settings.AvailableLanguages"] = self.getAvailableLanguages() - website.settings["Settings.AvailableDocLanguages"] = self.getAvailableDocLanguages() - #self.log.info(self.settings) - - - def print_foo(self): - '''a stupid demo method - - if there are methods necessary for more than one site, - put them in here like this stupid demo''' - self.log.info("'print_foo' was called by some site and triggerd an inheritated method") - self.cbx_inheritance_test("fooooooooooooobaaaaaaaaaaaaaaaaaaaar") - diff --git a/pythonrewrite/bin2/CryptoBoxWebserverSites.py b/pythonrewrite/bin2/CryptoBoxWebserverSites.py deleted file mode 100755 index a3404a0..0000000 --- a/pythonrewrite/bin2/CryptoBoxWebserverSites.py +++ /dev/null @@ -1,258 +0,0 @@ -import CryptoBox -import CryptoBoxWebserverSettings -import CryptoBoxWebserverRender -# RFC: is this global variable necessary? [l] -website = CryptoBoxWebserverRender.CryptoBoxWebserverRender() - -# RFC: where should we put the information gathering? (available harddisks, current volume info, ...) - selectively for every "site" or always (as before)? [l] - -# RFC: is it necessary to inherit these both classes? -# for clarity they should be just instanciated - or not? [l] -class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettings.CryptoBoxWebserverSettings): - ''' - url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'} - ''' - - def __prepare(self, action="show_status"): - '''handles stuff that all sites need as preparation - - The default site to render is 'show_status'. - Self.settings is filled by the following methodcall - thus every rendered site will get actual values from the configfile. - After that the corresponding site-method (e.g. doc) may set individual values. - ''' - - # RFC: the following line somehow implicitly calls 'setSettings(self, self)' - # should it be that way? [l] - self.setSettings(self) - #self.settings - self.settings["Data.Action"] = action - #TODO: check ssl status - - - def __sanitize_input(self, evilparams): - '''mistrusts every given parameter and wipes crap out - - Every single site method has to call this before even looking - at url-given parameters. - This has to be called manually, since I don't see any other way of - sanitizing input automatically for all sites. - - To take full effect it is good style not to use any given - parameter for any website. Instead use "settings.["..." if it - isn't already defined. Then define it in here, after carefully - checking. - # RFC: why shouldn't it be called in __init__? [l] - there is no such thing like __init__ in cherrypy sites [a] - what about the unnamed place, where 'exposed' attributes are set? [l] - ''' - # RFC: this dictionary is not sufficient for arbitrary text inputs (e.g.: names) or numbers [l] - # what way would we sanizite such input? just exclude forbidden elements? [a] - # I would prefer a seperate function for each possible setting [l] - niceparams = { - 'weblang': ["Settings.Language", self.settings["Settings.AvailableLanguages"]], - 'loglevel': ["Log.Level", ('','info', 'warn', 'debug', 'error')], - 'type': ["Data.Type", ('reboot', 'poweroff')] - } - ## check all given evil parameters against the nice ones - ## set them to self.settings if accepted, otherwise do nothing - for evilkey in evilparams.keys(): - # TODO: should be easier without the following for-loop - for nicekey in niceparams.keys(): - if evilkey == nicekey: - #self.log.warn(niceparams[nicekey][0]) - #self.log.warn(niceparams[nicekey][1]) - if evilparams[nicekey] and evilparams[nicekey] in niceparams[nicekey][1]: - # RFC: isn't "self.settings" a non-obvious name for user input? [l] - # self.settings is used by clearsilver [a] - # yes, but why should clearsilver have access to the user input? [l] - self.settings[niceparams[nicekey][0]] = evilparams[nicekey] - #self.log.warn(niceparams[nicekey][0]) - #self.log.warn(evilparams[nicekey]) - - ''' - ## e.g. do this manually - if evilkey == "weblang": - if evilparams["weblang"] and evilparams["weblang"] in niceparams["weblang"]: - self.settings["Settings.Language"] = evilparams["weblang"] - if evilkey == "loglevel": - if evilparams["loglevel"] and evilparams["loglevel"] in niceparams["loglevel"]: - self.settings["Log.Level"] = evilparams["loglevel"] - if evilkey == "type": - if evilparams["type"] and evilparams["type"] in niceparams["type"]: - self.settings["Data.Type"] = evilparams["type"] - ''' - - return - - def __isHDAvailable(self): - #TODO: implement this - return True - - def __check_config(self): - #TODO: from now on a cryptobox is always configured - return True - - - def __check_init_running(self): - #TODO: implement this check (is mkfs still running?) - return False - - ###################################################################### - ## put real sites down here and don't forget to expose them at the end - - def logs(self, loglevel=""): - '''displays a HTML version of the logfile - - The loglevel has to be set and nothing else, as we just log in english. - RFC: what does this mean? We still have to save the current language - or not? [l] - - Be aware not to name this method just "log" as it seems to be a - reserved word. - # RFC: maybe it conflicts with CryptoBoxProps.log - which we inherited? [l] - ''' - self.__prepare("show_log") - self.__sanitize_input({"loglevel":loglevel}) - self.settings["Data.Log"] = "
".join(self.getLogData(lines=30, maxSize=2000)) - return website.render(self) - - - def status(self, weblang=""): - '''shows the current status of the box - ''' - self.__prepare("show_status") - self.__sanitize_input({"weblang":weblang}) - if not self.__check_config(): - self.settings["Data.Warning"] = "NotInitialized" - self.settings["Data.Action"] = "form_init" - elif self.__check_init_running(): - self.settings["Data.Warning"] = "InitNotFinished" - self.settings["Data.Action"] = "empty" - self.settings["Data.Redirect.Action"] = "form_config" - self.settings["Data.Redirect.Delay"] = "30" - else: - self.settings["Data.Action"] = "show_status" - self.settings["Data.Redirect.Delay"] = "60" - return website.render(self) - - - def config(self,weblang=""): - pass - - - # TODO: add "doclang" - it is selected by each link in the doc pages - # according to scripts/docexport it's weblang [a] - def doc(self,page="",weblang=""): - '''prints the offline wikipage - ''' - self.__prepare("show_doc") - # TODO: single pagenames should be sanitized - self.__sanitize_input({"weblang":weblang}) - # TODO: check the supplied page name for validity (is it text? pattern match?) - if page: - self.settings["Data.Doc.Page"] = page - else: - ## display this site as default helpsite - self.settings["Data.Doc.Page"] ="CryptoBoxUser" - if len(self.settings["Settings.AvailableDocLanguages"]) < 1: - self.settings["Data.Error"] = "NoDocumentation" - # TODO: what should be done, if there is an error? - # do you mean this is not an error? [a] - # it is, but the current action is still "show_doc" - despite the error - maybe "blank" would be better? [l] - ## set doclang to weblang, otherwise the default weblang from the config will be used for doclang - elif self.settings["Settings.Language"] in self.settings["Settings.AvailableDocLanguages"]: - self.settings["Settings.DocLang"] = self.settings["Settings.Language"] - # TODO: missing 'else'? - - return website.render(self) - - - def system(self, type="", weblang=""): - self.__prepare("form_system") - self.__sanitize_input({"type":type,"weblang":weblang}) - if type == "reboot": - self.settings["Data.Success"] = "ReBoot" - self.settings["Data.Redirect.Action"] = "show_status" - self.settings["Data.Redirect.Delay"] = "180" - self.log.info("TODO: call function for system reboot") - elif type == "poweroff": - self.settings["Data.Success"] = "PowerOff" - self.log.info("TODO: call function for system shutdown") - else: - self.log.warn("This shutdown-mode (%s) is not supplied." % type) - return website.render(self) - - - def index(self): - self.__prepare("show_status") - return website.render(self) - - def test(self): - return "test passed" - - def umount_do(self): - if not __isHDAvailable(): - pass - else: - pass - - ''' - ## DONE: these functions are pythonized - #################### show_log ####################### - ##################### doc ############################ - ##################### poweroff ###################### - ##################### reboot ######################## - - ## but there are even more TODO - #-------------------------------------------------------# - # here you may define all cases that require a harddisk # - #-------------------------------------------------------# - ################ umount_do ####################### - elif action == "unmount_do": - if not device: - self.log.debug("invalid device chosen: %s" device - settings["Data.Warning"] = "InvalidDevice" - settings["Data.Action"] = "empty" - elif not True: #TODO: replace True with check_config() - settings["Data.Warning"] = "NotInitialized" - settings["Data.Action"] = "form_init" - elif True: #TODO: replace True with check_init_running() - settings["Data.Warning"] = "InitNotFinished" - settings["Data.Action"] = "empty" - settings["Data.Redirect.Action"] = "form_config" - settings["Data.Redirect.Delay"] = "30" - elif not True: #TODO: replace True with check_mounted(device) - settings["Data.Warning"] = "NotMounted" - settings["Data.Action"] = "show_volume" - else: #unmount - #TODO: replace this line with umount_vol(device) - if True: #TODO: replace True with check_mounted(device) - settings["Data.Warning"] = "UmountFailed" - settings["Data.Action"] = "show_volume" - else: - settings["Data.Action"] = "show_volume" - ################ mount_do ######################## - elif action == "mount_do": - if device: - pass #TODO: is_encrypted = check_device_encryption(device) - else: - self.log.debug("invalid device chosen: %s" device - settings["Data.Warning"] = "InvalidDevice" - settings["Data.Action"] = "empty" - elif not True: #TODO: replace True with check_config() - settings["Data.Warning"] = "NotInitialized" - settings["Data.Action"] = "form_init" - #at cryptobox.pl line 568 - ''' - - - ############################################################################ - ## to make the sites visible through the webserver they must be exposed here - index.exposed = True - doc.exposed = True - logs.exposed = True - system.exposed = True - status.exposed = True - test.exposed = True - - diff --git a/pythonrewrite/bin2/WebInterfaceDataset.py b/pythonrewrite/bin2/WebInterfaceDataset.py new file mode 100644 index 0000000..2b61cdd --- /dev/null +++ b/pythonrewrite/bin2/WebInterfaceDataset.py @@ -0,0 +1,74 @@ +import os +import CryptoBoxContainer + +## useful constant for many functions +CONT_TYPES = CryptoBoxContainer.CryptoBoxContainer.Types + +class WebInterfaceDataset(dict): + """this class contains all data that should be available for the clearsilver + templates + """ + + def __init__(self, cbox, prefs): + self.prefs = prefs + self.cbox = cbox + self.__setConfigValues() + self.__setCryptoBoxState() + + + def __setConfigValues(self): + self["Settings.TemplateDir"] = os.path.abspath(self.prefs["Locations"]["TemplateDir"]) + self["Settings.LanguageDir"] = os.path.abspath(self.prefs["Locations"]["LangDir"]) + self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"]) + self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"] + self["Settings.Language"] = self.prefs["WebSettings"]["Language"] + self["Settings.DocLang"] = self.prefs["WebSettings"]["DocLanguage"] + + + def __setCryptoBoxState(self): + avail_counter = 0 + active_counter = 0 + for container in self.cbox.getContainerList(): + isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 + isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 + isMounted = container.isMounted() and 1 or 0 + self["Data.Disks.%d.device" % avail_counter] = container.getDevice() + self["Data.Disks.%d.name" % avail_counter] = container.getName() + self["Data.Disks.%d.encryption" % avail_counter] = isEncrypted + self["Data.Disks.%d.plaintext" % avail_counter] = isPlain + self["Data.Disks.%d.active" % avail_counter] = isMounted + if isMounted: active_counter += 1 + avail_counter += 1 + self["Data.activeDisksCount"] = active_counter + for lang in self.cbox.getAvailableLanguages(): + self["Data.Languages." + lang] = self.__getLanguageName(lang) + ## TODO: open issues: Data.Config.AdminPasswordIsSet + + + def setCurrentDiskState(self, device): + for container in self.cbox.getContainerList(): + if container.getDevice() == device: + isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 + isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 + isMounted = container.isMounted() and 1 or 0 + self["Data.CurrentDisk.device"] = container.getDevice() + self["Data.CurrentDisk.name"] = container.getName() + self["Data.CurrentDisk.encryption"] = isEncrypted + self["Data.CurrentDisk.plaintext"] = isPlain + self["Data.CurrentDisk.active"] = isMounted + + if isMounted: + (size, avail, used) = container.getCapacity() + percent = used / size + self["Data.CurrentDisk.capacity.used"] = used + self["Data.CurrentDisk.capacity.free"] = avail + self["Data.CurrentDisk.capacity.size"] = size + self["Data.CurrentDisk.capacity.percent"] = percent + + def __getLanguageName(self, lang): + import neo_cgi, neo_util, neo_cs + hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf") + hdf = neo_util.HDF() + hdf.readFile(hdf_path) + return hdf.getValue("Lang.Name",lang) + diff --git a/pythonrewrite/bin2/WebInterfaceSites.py b/pythonrewrite/bin2/WebInterfaceSites.py new file mode 100755 index 0000000..29be594 --- /dev/null +++ b/pythonrewrite/bin2/WebInterfaceSites.py @@ -0,0 +1,470 @@ +import CryptoBox +import WebInterfaceDataset +import re + +class WebInterfaceSites: + ''' + url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'} + ''' + + + def __init__(self): + import logging + self.cbox = CryptoBox.CryptoBoxProps() + self.log = logging.getLogger("CryptoBox") + self.prefs = self.cbox.cbxPrefs + self.__resetDataset() + + + def __resetDataset(self): + self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs) + + + def __isHDAvailable(self): + #TODO: implement this + return True + + + def __check_config(self): + #TODO: from now on a cryptobox is always configured + return True + + + def __check_init_running(self): + #TODO: implement this check (is mkfs still running?) + return False + + + ###################################################################### + ## put real sites down here and don't forget to expose them at the end + + def logs(self, weblang=""): + '''displays a HTML version of the logfile + ''' + self.__resetDataset() + self.__setWebLang(weblang) + self.dataset["Data.Log"] = "
".join(self.cbox.getLogData(lines=30, maxSize=2000)) + return self.__render("show_log") + + + def status(self, weblang=""): + '''shows the current status of the box + ''' + self.__resetDataset() + self.__setWebLang(weblang) + if not self.__check_config(): + self.dataset["Data.Warning"] = "NotInitialized" + return self.__render("form_init") + elif self.__check_init_running(): + self.dataset["Data.Warning"] = "InitNotFinished" + self.dataset["Data.Redirect.Action"] = "form_config" + self.dataset["Data.Redirect.Delay"] = "30" + return self.__render("empty") + else: + self.dataset["Data.Redirect.Delay"] = "60" + return self.__render("show_status") + + + def config(self,weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + pass + + + def doc(self,page="",weblang=""): + '''prints the offline wikipage + ''' + import re + self.__resetDataset() + self.__setWebLang(weblang) + + ## check for invalid characters + if page and not re.search(u'\W', page): + self.dataset["Data.Doc.Page"] = page + else: + ## display this page as default help page + self.dataset["Data.Doc.Page"] ="CryptoBoxUser" + + return self.__render("show_doc") + + + def system(self, shutdowntype="", weblang=""): + # TODO: check weblang + self.__resetDataset() + self.__setWebLang(weblang) + if shutdowntype == "reboot": + self.dataset["Data.Success"] = "ReBoot" + self.dataset["Data.Redirect.Action"] = "show_status" + self.dataset["Data.Redirect.Delay"] = "180" + self.log.info("TODO: call function for system reboot") + elif shutdowntype == "poweroff": + self.dataset["Data.Success"] = "PowerOff" + self.log.info("TODO: call function for system shutdown") + else: + self.log.warn("This shutdown-mode (%s) is not supported." % shutdowntype) + return self.__render("form_system") + + + def index(self, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + return self.__render("show_status") + + + def show_volume(self, device="", weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + return self.__render("show_volume") + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + + + def show_volumes(self, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + return self.__render("show_volumes") + + + def volume_name_set(self, device="", volume_name="", weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + volume_name = volume_name.strip() + if self.__checkVolumeName(volume_name): + container = self.cbox.getContainer(device) + try: + container.setName(volume_name) + # TODO: specify the possible exceptions + except Exception: + self.log.warn("failed to rename the volume '%s' to '%s'" % (device, volume_name)) + self.dataset["Data.Warning"] = "SetVolumeNameFailed" + else: + self.log.info("successfully renamed volume '%s' to '%s'" % (device, volume_name)) + # reread the dataset + self.__resetDataset() + self.dataset.setCurrentDiskState(device) + else: + self.dataset["Data.Warning"] = "InvalidVolumeName" + return self.__render("show_volume") + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + + + def mount_do(self, device, crypto_password=None, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + container = self.cbox.getContainer(device) + if container.isMounted(): + self.dataset["Data.Warning"] = "IsMounted" + self.log.warn("the device (%s) is already mounted" % device) + else: + try: + if container.getType() == container.Types["luks"]: + ## encrypted luks container + if not crypto_password: + self.dataset["Data.Warning"] = "EmptyCryptoPassword" + self.log.warn("no password was supplied for mounting of device '%s'" % device) + return self.__render("show_volume") + else: + container.mount(crypto_password) + elif container.getType() == container.Types["plain"]: + ## plain container + container.mount() + else: + ## mounting is not possible + # TODO: wrong warning message - replace it + self.dataset["Data.Warning"] = "MountFailed" + self.log.warn("this type of container (%s) cannot be mounted - sorry!" % device) + except (Exception, "MountError"): + self.dataset["Data.Warning"] = "MountFailed" + self.log.warn("failed to mount the device (%s)" % device) + else: + self.log.info("successfully mounted the container (%s)" % device) + # reread the dataset + self.__resetDataset() + self.dataset.setCurrentDiskState(device) + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + return self.__render("show_volume") + + + def volume_init_ask(self, device, encryption=None, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + container = self.cbox.getContainer(device) + if container.isMounted(): + self.dataset["Data.Warning"] = "VolumeMayNotBeMounted" + self.log.warn("initialization is not possible as long as the device (%s) is mounted" % device) + return self.__render("show_volume") + else: + if encryption is None: + self.dataset["Data.Init.isCrypto"] = 0 + else: + self.dataset["Data.Init.isCrypto"] = 1 + return self.__render("form_init") + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + + + def init_do(self, device, confirm, crypto_password=None, crypto_password2=None, encryption=None, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + container = self.cbox.getContainer(device) + ## set 'Data.Init.isCrypto' - just in case, we have to show the same form again + if encryption is None: + self.dataset["Data.Init.isCrypto"] = 0 + else: + self.dataset["Data.Init.isCrypto"] = 1 + if container.isMounted(): + self.dataset["Data.Warning"] = "VolumeMayNotBeMounted" + self.log.warn("initialization is not possible as long as the device (%s) is mounted" % device) + return self.__render("form_init") + else: + # TODO: we have to compare 'confirm' with the value in the language file - IMPORTANT! + if not confirm: + self.dataset["Data.Warning"] = "InitNotConfirmed" + self.log.warn("the confirmation sentence for initialization of the device '%s' was wrong" % device) + return self.__render("form_init") + try: + if not encryption is None: + if not crypto_password: + self.dataset["Data.Warning"] = "EmptyCryptoPassword" + self.log.warn("no crypto password was supplied for initialization of device '%s'" % device) + return self.__render("form_init") + if crypto_password != crypto_password2: + self.dataset["Data.Warning"] = "DifferentCryptoPasswords" + self.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % device) + return self.__render("form_init") + container.create(container.Types["luks"], crypto_password) + else: + container.create(container.Types["plain"]) + # TODO: specify the exception + except Exception, errMsg: + # TODO: wrong error/warning message - change it + self.dataset["Data.Error"] = "InitFailed" + self.log.warn("initialization of device '%s' failed" % device) + self.log.warn("reason: %s" % errMsg) + return self.__render("form_init") + else: + self.log.info("successfully initialized device '%s'" % device) + # reread the dataset + self.__resetDataset() + self.dataset.setCurrentDiskState(device) + return self.__render("show_volume") + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + + + def test(self): + self.__resetDataset() + return "test passed" + + + def umount_do(self, device, weblang=""): + self.__resetDataset() + self.__setWebLang(weblang) + if self.__setDevice(device): + container = self.cbox.getContainer(device) + if not container.isMounted(): + self.dataset["Data.Warning"] = "NotMounted" + self.log.warn("the device (%s) is currently not mounted" % device) + else: + try: + if container.getType() == container.Types["luks"]: + ## encrypted luks container + container.umount() + elif container.getType() == container.Types["plain"]: + ## plain container + container.umount() + else: + ## mounting is not possible + # TODO: wrong warning message - replace it + self.dataset["Data.Warning"] = "UmountFailed" + self.log.warn("this type of container (%s) cannot be umounted - sorry!" % device) + except (Exception, "UmountError"): + self.dataset["Data.Warning"] = "UmountFailed" + self.log.warn("failed to unmount the device (%s)" % device) + else: + self.log.info("successfully unmounted the container (%s)" % device) + # reread the dataset + self.__resetDataset() + self.dataset.setCurrentDiskState(device) + else: + if self.cbox.getContainerList(): + return self.__render("show_volumes") + else: + return self.__render("show_status") + return self.__render("show_volume") + + + ''' + ## DONE: these functions are pythonized + #################### show_log ####################### + ##################### doc ############################ + ##################### poweroff ###################### + ##################### reboot ######################## + + ## but there are even more TODO + #-------------------------------------------------------# + # here you may define all cases that require a harddisk # + #-------------------------------------------------------# + ################ umount_do ####################### + elif action == "unmount_do": + if not device: + self.log.debug("invalid device chosen: %s" device + settings["Data.Warning"] = "InvalidDevice" + settings["Data.Action"] = "empty" + elif not True: #TODO: replace True with check_config() + settings["Data.Warning"] = "NotInitialized" + settings["Data.Action"] = "form_init" + elif True: #TODO: replace True with check_init_running() + settings["Data.Warning"] = "InitNotFinished" + settings["Data.Action"] = "empty" + settings["Data.Redirect.Action"] = "form_config" + settings["Data.Redirect.Delay"] = "30" + elif not True: #TODO: replace True with check_mounted(device) + settings["Data.Warning"] = "NotMounted" + settings["Data.Action"] = "show_volume" + else: #unmount + #TODO: replace this line with umount_vol(device) + if True: #TODO: replace True with check_mounted(device) + settings["Data.Warning"] = "UmountFailed" + settings["Data.Action"] = "show_volume" + else: + settings["Data.Action"] = "show_volume" + ################ mount_do ######################## + elif action == "mount_do": + if device: + pass #TODO: is_encrypted = check_device_encryption(device) + else: + self.log.debug("invalid device chosen: %s" device + settings["Data.Warning"] = "InvalidDevice" + settings["Data.Action"] = "empty" + elif not True: #TODO: replace True with check_config() + settings["Data.Warning"] = "NotInitialized" + settings["Data.Action"] = "form_init" + #at cryptobox.pl line 568 + ''' + + + ##################### input checker ########################## + def __setWebLang(self, value): + ## TODO: add some code to evaluate the language setting of the browser + guess = value + availLangs = self.cbox.getAvailableLanguages() + ## TODO: add some warnings for an invalid choosen language + if not guess or \ + not guess in availLangs or \ + re.search(u'\W', guess): + guess = self.prefs["WebSettings"]["Language"] + ## maybe the language is still not valid + if not guess in availLangs: + self.log.warn("the configured language is invalid: %s" % guess) + guess = availLangs[0] + self.dataset["Settings.Language"] = guess + self.dataset["Settings.DocLang"] = guess + self.dataset["Settings.LinkAttrs.weblang"] = guess + + + def __setDevice(self, device): + if device and re.match(u'[\w /\-]+$', device) and self.cbox.getContainer(device): + self.log.debug("select device: %s" % device) + self.dataset.setCurrentDiskState(device) + return True + else: + self.log.warn("invalid device: %s" % device) + self.dataset["Data.Warning"] = "InvalidDevice" + return False + + + def __checkVolumeName(self, name): + if name and re.match(u'[\w \-]+$', name): + return True + else: + return False + + + def __render(self, template): + '''renders from clearsilver templates and returns the resulting html + + Gets a dictionary with all settings, nessessary for rendering. + In fact the dictionary is a copy of the CryptoBoxWerbserverSite + object, that calls this render method. This might be bloat but + this way the render method has always a complete, actual set of values. + ''' + + import os + try: + import neo_cgi, neo_util, neo_cs + except ImportError: + errorMsg = "Could not import clearsilver modules. Try 'apt-get install python-clearsilver'." + self.log.error(errorMsg) + sys.stderr.write(errorMsg) + raise ImportError, errorMsg + + self.dataset["Data.Action"] = template + self.log.info("rendering site: " + template) + + cs_path = os.path.join(self.prefs["Locations"]["TemplateDir"], "main.cs") + if not os.access(cs_path, os.R_OK): + log.error("Couldn't read clearsilver file: %s" % cs_path) + return "Couldn't read clearsilver file: %s" % cs_path + + # use the user selected language instead of the configured + hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], self.dataset["Settings.Language"] + ".hdf") + if not os.access(hdf_path, os.R_OK): + log.error("Couldn't read language file: %s" % hdf_path) + return "Couldn't read language file: %s" % hdf_path + + hdf = neo_util.HDF() + hdf.readFile(hdf_path) + self.log.debug(self.dataset) + for key in self.dataset.keys(): + hdf.setValue(key,str(self.dataset[key])) + cs = neo_cs.CS(hdf) + cs.parseFile(cs_path) + return cs.render() + + + ############################################################################ + ## to make the sites visible through the webserver they must be exposed here + index.exposed = True + doc.exposed = True + logs.exposed = True + system.exposed = True + status.exposed = True + show_volume.exposed = True + volume_name_set.exposed = True + mount_do.exposed = True + volume_init_ask.exposed = True + init_do.exposed = True + umount_do.exposed = True + show_volumes.exposed = True + test.exposed = True + + + """ + ## TODO: check this before anything else + if self.cbox.getAvailableDocLanguages(): + self.dataset["Data.Error"] = "NoDocumentation" + return self.__render("show_status") + """ diff --git a/pythonrewrite/bin2/cryptobox.conf b/pythonrewrite/bin2/cryptobox.conf index 244a08a..397ffaf 100644 --- a/pythonrewrite/bin2/cryptobox.conf +++ b/pythonrewrite/bin2/cryptobox.conf @@ -59,7 +59,7 @@ Stylesheet = /cryptobox-misc/cryptobox.css Language = de # default language for documentation -DocLang = de +DocLanguage = de [Programs] diff --git a/pythonrewrite/bin2/filehandling.py b/pythonrewrite/bin2/filehandling.py deleted file mode 100755 index e69de29..0000000 diff --git a/pythonrewrite/lang/de.hdf b/pythonrewrite/lang/de.hdf index 18c08ff..47e3686 100644 --- a/pythonrewrite/lang/de.hdf +++ b/pythonrewrite/lang/de.hdf @@ -14,6 +14,7 @@ Lang { Log = Protokoll der CryptoBox System = System Status = Status der CryptoBox + Volume = Eigenschaften von } @@ -40,6 +41,12 @@ Lang { Configuration = Einstellungen CryptoIsActive = Die Crypto-Daten sind verfügbar. CryptoIsDown = Die Crypto-Daten sind vor jedem Zugriff geschützt. + ChoosePartition = Welchen Daten-Container möchtest du auswählen? + ChosenPartition = Der aktuelle Daten-Container ist + ActivePartitions = Die folgenden Daten-Container sind derzeit aktiv + PassivePartitions = Die folgenden Daten-Container sind derzeit inaktiv + ContainerName = Der Name des Daten-Containers + ContainerEncryption = Aktiviere Verschlüsselung } @@ -56,6 +63,8 @@ Lang { Documentation = Hilfe Status = Status System = System + ContainerNameSet = Setze den neuen Namen + InitContainer = Reinitialisiere den Container } @@ -154,6 +163,36 @@ Lang { Title = Änderung der Netzwerk-Adresse Text = Die Netzwerk-Adresse der CryptoBox wurde verändert. In wenigen Sekunden werden sie zu der neuen Adresse umgeleitet. } + + NoDiskAvailableForMount { + Title = Kein Daten-Container verfügbar + Text = Es ist kein inaktiver Daten-Container verfügbar. Vielleicht sind bereits alle Container aktiv? + } + + NoDiskAvailableForUmount { + Title = Kein Daten-Container verfügbar + Text = Kein Daten-Container ist aktiv. Vielleicht wurden alle Container deaktiviert. + } + + InvalidDevice { + Title = Ungültiger Container + Text = Der angegebene Daten-Container ist nicht zulässig. + } + + InvalidVolumeName { + Title = Umbenennung fehlgeschlagen + Text = Der gewählte neue Name des Containers ist ungültig. Versuche es erneut. + } + + SetVolumeNameFailed { + Title = Umbenennung fehlgeschlagen + Text = Die Umbenennung des Containers schlug fehl. Details findest du in der Log-Datei. + } + + VolumeMayNotBeMounted { + Title = Der Container ist derzeit aktiv + Text = Die gewünschte Aktion kann nicht durchgeführt werden, solange der Container aktiv ist. + } } diff --git a/pythonrewrite/lang/en.hdf b/pythonrewrite/lang/en.hdf index 1602e9f..7c3bb34 100644 --- a/pythonrewrite/lang/en.hdf +++ b/pythonrewrite/lang/en.hdf @@ -45,7 +45,7 @@ Lang { ChosenPartition = The chosen container is ActivePartitions = The following containers are enabled PassivePartitions = The following containers are disabled - ContainerName = Container's name: + ContainerName = Container's name ContainerEncryption = Enable encryption } diff --git a/pythonrewrite/templates/form_config.cs b/pythonrewrite/templates/form_config.cs index 4b94e31..28d8742 100644 --- a/pythonrewrite/templates/form_config.cs +++ b/pythonrewrite/templates/form_config.cs @@ -3,7 +3,7 @@

- +


@@ -26,7 +26,6 @@

- diff --git a/pythonrewrite/templates/form_init.cs b/pythonrewrite/templates/form_init.cs index 3118718..61d0c63 100644 --- a/pythonrewrite/templates/form_init.cs +++ b/pythonrewrite/templates/form_init.cs @@ -3,14 +3,19 @@

- +


- + +

+

+ + +
diff --git a/pythonrewrite/templates/form_init_partition.cs b/pythonrewrite/templates/form_init_partition.cs index 91bee8a..860ef78 100644 --- a/pythonrewrite/templates/form_init_partition.cs +++ b/pythonrewrite/templates/form_init_partition.cs @@ -2,7 +2,7 @@

- +

@@ -27,7 +27,6 @@

-

diff --git a/pythonrewrite/templates/form_mount.cs b/pythonrewrite/templates/form_mount.cs index bf5c8fd..9c16061 100644 --- a/pythonrewrite/templates/form_mount.cs +++ b/pythonrewrite/templates/form_mount.cs @@ -10,7 +10,7 @@
- + 1 ?>

@@ -30,7 +30,6 @@ ?>

- diff --git a/pythonrewrite/templates/form_umount.cs b/pythonrewrite/templates/form_umount.cs index 3a5b2ac..2183413 100644 --- a/pythonrewrite/templates/form_umount.cs +++ b/pythonrewrite/templates/form_umount.cs @@ -1,6 +1,6 @@ - + @@ -9,25 +9,28 @@

- + - 1 ?> + 1 ?>

+

:

+ var:act_name ?>

+ var:act_device ?>"/> - diff --git a/pythonrewrite/templates/header.cs b/pythonrewrite/templates/header.cs index 6b2bf36..ede42a2 100644 --- a/pythonrewrite/templates/header.cs +++ b/pythonrewrite/templates/header.cs @@ -16,7 +16,7 @@ - 0 ?> + 0 ?>
@@ -24,14 +24,13 @@
- ">
- 0 ?> + 0 ?>
diff --git a/pythonrewrite/templates/macros.cs b/pythonrewrite/templates/macros.cs index 83863d7..e094019 100644 --- a/pythonrewrite/templates/macros.cs +++ b/pythonrewrite/templates/macros.cs @@ -75,8 +75,8 @@ def:link(path, attr1, value1, attr2, value2) ?>
" method="post" enctype="application/x-www-from-urlencoded" accept-charset="utf-8">" method="post" enctype="application/x-www-from-urlencoded" accept-charset="utf-8"> diff --git a/pythonrewrite/templates/nav.cs b/pythonrewrite/templates/nav.cs index ac1aecd..882c7ed 100644 --- a/pythonrewrite/templates/nav.cs +++ b/pythonrewrite/templates/nav.cs @@ -6,14 +6,14 @@ - 1 ?>" title=""> diff --git a/pythonrewrite/templates/show_status.cs b/pythonrewrite/templates/show_status.cs index 06efffc..8971a73 100644 --- a/pythonrewrite/templates/show_status.cs +++ b/pythonrewrite/templates/show_status.cs @@ -2,27 +2,27 @@

- +

Sorry - you should have never seen this ...

- + - + - 0 ?> + 0 ?>

: -

    +
    - 0 ?> + ?>">
+

: -

    +
    + ?>">
diff --git a/pythonrewrite/templates/show_volume.cs b/pythonrewrite/templates/show_volume.cs index 61d7174..4629d48 100644 --- a/pythonrewrite/templates/show_volume.cs +++ b/pythonrewrite/templates/show_volume.cs @@ -7,21 +7,19 @@

Mount container

- +

-

Unmount container

- +

-

@@ -30,11 +28,10 @@

Change the name of the container

- +

-

@@ -43,11 +40,10 @@

Reinitialize container

- +

-

@@ -64,8 +60,7 @@
  • Size of container:
  • Available space of container:
  • -
  • Used space of container: /
  • +
  • Used space of container: %
  • diff --git a/pythonrewrite/templates/show_volumes.cs b/pythonrewrite/templates/show_volumes.cs index 05df5aa..dc55505 100644 --- a/pythonrewrite/templates/show_volumes.cs +++ b/pythonrewrite/templates/show_volumes.cs @@ -1,6 +1,8 @@ - + + +