diff --git a/pythonrewrite/plugins/date/date.py b/pythonrewrite/plugins/date/date.py
index 99f705a..a44ed0d 100644
--- a/pythonrewrite/plugins/date/date.py
+++ b/pythonrewrite/plugins/date/date.py
@@ -3,6 +3,9 @@ import CryptoBoxPlugin
class date(CryptoBoxPlugin.CryptoBoxPlugin):
+ pluginCapabilities = [ "system" ]
+ requestAuth = False
+
def doAction(self, store=None, year=0, month=0, day=0, hour=0, minute=0):
import datetime
if store:
diff --git a/pythonrewrite/plugins/format_fs/format_fs.py b/pythonrewrite/plugins/format_fs/format_fs.py
new file mode 100644
index 0000000..cd32640
--- /dev/null
+++ b/pythonrewrite/plugins/format_fs/format_fs.py
@@ -0,0 +1,93 @@
+import CryptoBoxPlugin
+
+class format_fs(CryptoBoxPlugin.CryptoBoxPlugin):
+
+ pluginCapabilities = [ "volume" ]
+ requestAuth = True
+
+ ## map filesystem types to the appropriate arguments for 'mkfs'
+ fsTypes = {
+ "windows": "vfat",
+ "linux": "ext3" }
+
+ containerTypes = [ "luks", "plain" ]
+
+
+ def doAction(self, store=None, fs_type="windows", container_type="luks", crypto_password=None, crypto_password2=None, confirm=None):
+ if not fs_type in self.fsTypes.keys():
+ self.cbox.info
+ return "format_volume"
+ self.hdf[self.hdf_prefix + "fs_type"] = fs_type
+ self.hdf[self.hdf_prefix + "container_type"] = container_type
+ for t in self.fsTypes.keys():
+ self.hdf[self.hdf_prefix + "fs_types." + t] = t
+ if store == "step1":
+ if not confirm:
+ self.cbox.log.warn("missing confirmation for formatting of filesystem: %s" % self.device)
+ self.hdf["Data.Warning"] = "Plugins.format_fs.FormatNotConfirmed"
+ return "volume_format"
+ if container_type == "luks":
+ return "volume_format_luks"
+ elif container_type == "plain":
+ return self.__format_plain(fs_type)
+ elif store == "step2":
+ if container_type == "luks":
+ return self.__format_luks(fs_type, crypto_password, crypto_password2)
+ else:
+ self.cbox.log.info("invalid input value for 'container_type': %s" % container_type)
+ return "volume_format"
+ elif store:
+ self.cbox.log.info("invalid input value for 'store': %s" % store)
+ return "volume_format"
+ else:
+ return "volume_format"
+
+
+ def getStatus(self):
+ return "no status"
+
+
+ def __format_plain(self, fsType):
+ try:
+ container = self.cbox.getContainer(self.device)
+ container.create(container.Types["plain"])
+ except CBVolumeIsActive:
+ self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
+ self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
+ return None
+ except CBContainerError, errMsg:
+ self.hdf["Data.Warning"] = "Plugins.format_fs.FormatFailed"
+ self.cbox.log.warn("initialization of device '%s' failed" % self.device)
+ self.cbox.log.warn("reason: %s" % errMsg)
+ return "volume_format"
+ else:
+ self.cbox.log.info("successfully initialized device '%s'" % self.device)
+ return None
+
+
+ def __format_luks(self, fsType, pw, pw2):
+ if not pw:
+ self.hdf["Data.Warning"] = "EmptyCryptoPassword"
+ self.cbox.log.warn("no crypto password was supplied for initialization of device '%s'" % self.device)
+ return "volume_format"
+ if pw != pw2:
+ self.hdf["Data.Warning"] = "DifferentCryptoPasswords"
+ self.cbox.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % self.device)
+ return "volume_format"
+ container = self.cbox.getContainer(self.device)
+ try:
+ container.create(container.Types["luks"], pw)
+ except CBVolumeIsActive:
+ self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
+ self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
+ return None
+ except CBContainerError, errMsg:
+ self.hdf["Data.Warning"] = "Plugins.format_fs.FormatFailed"
+ self.cbox.log.warn("initialization of device '%s' failed" % self.device)
+ self.cbox.log.warn("reason: %s" % errMsg)
+ return "volume_format"
+ else:
+ self.hdf["Data.Success"] = "Plugins.format_fs.FormatSuccess"
+ self.cbox.log.info("successfully initialized device '%s'" % self.device)
+ return None
+
diff --git a/pythonrewrite/plugins/format_fs/lang/en.hdf b/pythonrewrite/plugins/format_fs/lang/en.hdf
new file mode 100644
index 0000000..a9c8822
--- /dev/null
+++ b/pythonrewrite/plugins/format_fs/lang/en.hdf
@@ -0,0 +1,36 @@
+Name = Create filesystems
+Link = Format
+Rank = 60
+
+Title.Format = Initializing filesystem
+
+Button.Format = Initialize filesystem
+
+Text {
+ Confirm = Yes, I know what I am doing!
+ FormatWarning = All data of the selected filesystem will get lost!
+ FSType = Filesystem type
+ IsEncrypted = Encryption
+ Yes = Yes
+ No = No
+ UnmountBeforeInit = You must deactivate this volume before you may initialize it.
+}
+
+SuccessMessage {
+ FormatSuccess {
+ Title = Formatting successful
+ Text = The selected filesystem was successfully formatted.
+ }
+}
+
+WarningMessage {
+ FormatNotConfirmed {
+ Title = Confirmation missing
+ Text = You did not confirm this action by activating the checkbox.
+ }
+
+ FormatFailed {
+ Title = Formatting failed
+ Text = Formatting of the selected filesystem failed for unknown reasons - sorry!
+ }
+}
diff --git a/pythonrewrite/plugins/format_fs/volume_format.cs b/pythonrewrite/plugins/format_fs/volume_format.cs
new file mode 100644
index 0000000..fcdb219
--- /dev/null
+++ b/pythonrewrite/plugins/format_fs/volume_format.cs
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
Create configuration partition?
+
+
+
+
diff --git a/pythonrewrite/plugins/plugin-interface.txt b/pythonrewrite/plugins/plugin-interface.txt
index 0c69667..50cec84 100644
--- a/pythonrewrite/plugins/plugin-interface.txt
+++ b/pythonrewrite/plugins/plugin-interface.txt
@@ -5,34 +5,49 @@ The following directory structure is required:
Python code interface:
- - create a class with the same name as the plugin - it has to inherit CryptoBoxPlugin
+ - create a class with the same name as the plugin - it must inherit CryptoBoxPlugin
- function "doAction":
- this function will get called whenever this plugins is involved in a request
- all arguments should be optional (e.g. for displaying a form without previous input values)
- the argument "store" should be used to process a form submission (just a recommendation)
- - if the processing failed for some reason (invalid input, ...), it should manually set the "Data.Warning" (resp. "Data.Error" or "Data.Success") to a value of your choice (preferably you may want to use messages of your namespace (e.g. "Plugins.PLUGINNAME.InvalidInput"))
- - the return value should be the name of the template that should be displayed after processing (a template file in the plugin directory takes precedence over global template files)
+ - if the processing failed for some reason (invalid input, ...), it should manually set the
+ "Data.Warning" (resp. "Data.Error" or "Data.Success") to a value of your choice (preferably
+ you may want to use messages of your namespace (e.g. "Plugins.PLUGINNAME.InvalidInput"))
+ - the return value should be the name of the template that should be displayed after processing
+ (a template file in the plugin directory takes precedence over global template files)
- the return value may also be a dictionary with the following elements:
* template: the name of the template file (mandatory)
- * generator: a generator object ("yield") - its content will replace every occourence of "" in the template (useful for pages that are displayed step by step (as for formatting of filesystems))
- - an empty (e.g. None) return value can be used to go return to the plugin page
-
- - function "getStatus":
- - returns a string, that describes a state connected to this plugin (e.g. the current date and time (for the "date" plugin))
+ * generator: a generator object ("yield") - its content will replace every
+ occurrence of "" in the template (useful for pages that
+ are displayed step by step (as for formatting of filesystems))
+ - an empty (e.g. None) return value can be used to go to the default page (now: the
+ plugin overview)
+ - function "getStatus":
+ - returns a string, that describes a state connected to this plugin (e.g. the current date and
+ time (for the "date" plugin))
+ - the class variable "pluginCapabilities" must be an array of strings (supported: "system" and
+ "volume")
+ - the class variable "requestAuth" is boolean and defines, if admin authentication is necessary
+ for this plugin
+ - volume plugins contain the attribute "device" (you may trust this value - a volume plugin will
+ never get called with an invalid device)
Language file structure:
- - the content of the language file will be added to the hdf dataset below "Lang.Plugins.PLUGINNAME" (this avoids namespace conflicts)
+ - the content of the language file will be added to the hdf dataset below "Lang.Plugins.PLUGINNAME"
+ (this avoids namespace conflicts)
- the following values _must_ be defined:
Name (a short description)
Link (the visible text for links to this plugin)
Rank (defines the order of the plugins displayed (0..100))
- - all warnings, error and success messages should be stored below WarningMessage.??? (resp. ErrorMessage or SuccessMessage)
+ - all warnings, error and success messages should be stored below WarningMessage.???
+ (resp. ErrorMessage or SuccessMessage)
Clearsilver template:
- - should start with a "
" tag
+ - should start with a "
" tag (volume plugins: "h2")
- links to the plugin (e.g. in form headers) could look like the following:
- - a hidden input field called "store" should be used to indicate a form submission
+ - volume plugins must include "show_volume_[header|footer]" (see examples)
+
diff --git a/pythonrewrite/plugins/shutdown/form_shutdown.cs b/pythonrewrite/plugins/shutdown/form_shutdown.cs
new file mode 100644
index 0000000..23065c5
--- /dev/null
+++ b/pythonrewrite/plugins/shutdown/form_shutdown.cs
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pythonrewrite/plugins/shutdown/lang/en.hdf b/pythonrewrite/plugins/shutdown/lang/en.hdf
new file mode 100644
index 0000000..0a9efe2
--- /dev/null
+++ b/pythonrewrite/plugins/shutdown/lang/en.hdf
@@ -0,0 +1,34 @@
+Name = Shutdown or reboot the computer
+Link = Shutdown/Reboot
+Rank = 70
+
+Title.Shutdown = Shutdown computer
+
+Button.Shutdown = Poweroff
+Button.Reboot = Reboot
+
+Text.ShutdownInfo = You may turn off or reboot your CryptoBox here.
+
+SuccessMessage {
+ Shutdown {
+ Title = Shutting down the system
+ Text = If the computer does not turn off itself within a minute, then you should plug it off manually.
+ }
+
+ Reboot {
+ Title = Rebooting the system
+ Text = This may take a while (depending on your hardware) ...
+ }
+}
+
+WarningMessage {
+ ShutdownFailed {
+ Title = Shutdown failed
+ Text = Shutting down of the system failed for some reason - sorry!
+ }
+
+ RebootFailed {
+ Title = Reboot failed
+ Text = Reboot of the system failed for some reason - sorry!
+ }
+}
diff --git a/pythonrewrite/plugins/shutdown/root_action.py b/pythonrewrite/plugins/shutdown/root_action.py
new file mode 100755
index 0000000..ca98a47
--- /dev/null
+++ b/pythonrewrite/plugins/shutdown/root_action.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python2.4
+
+## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script
+PLUGIN_TYPE = "cryptobox"
+
+POWEROFF_BIN = "/sbin/poweroff"
+REBOOT_BIN = "/sbin/reboot"
+
+import subprocess
+import re
+import sys
+import os
+
+
+def call_prog(progy):
+ proc = subprocess.Popen(
+ shell = False,
+ args = [progy])
+ proc.communicate()
+ return proc.returncode == 0
+
+
+if __name__ == "__main__":
+ args = sys.argv[1:]
+
+ self_bin = sys.argv[0]
+
+ if len(args) > 1:
+ sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
+ sys.exit(1)
+
+ if len(args) == 0:
+ sys.stderr.write("%s: no argument supplied\n" % self_bin)
+ sys.exit(1)
+
+ if args[0] == "reboot":
+ result = call_prog(REBOOT_BIN)
+ elif args[0] == "shutdown":
+ result = call_prog(POWEROFF_BIN)
+ else:
+ sys.stderr.write("%s: illegal argument (%s)\n" % (self_bin, args[0]))
+ sys.exit(1)
+
+ if result:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
diff --git a/pythonrewrite/plugins/shutdown/shutdown.py b/pythonrewrite/plugins/shutdown/shutdown.py
new file mode 100644
index 0000000..bd40e38
--- /dev/null
+++ b/pythonrewrite/plugins/shutdown/shutdown.py
@@ -0,0 +1,50 @@
+import CryptoBoxPlugin
+
+REDIRECT_DELAY = 180
+
+class shutdown(CryptoBoxPlugin.CryptoBoxPlugin):
+
+ pluginCapabilities = [ "system" ]
+ requestAuth = False
+
+ def doAction(self, type=None):
+ if not type:
+ return "form_shutdown"
+ elif type == "shutdown":
+ if self.__doShutdown("shutdown"):
+ self.hdf["Data.Success"] = "Plugins.shutdown.Shutdown"
+ return None
+ else:
+ self.hdf["Data.Warning"] = "Plugins.shutdown.ShutdownFailed"
+ return "form_shutdown"
+ elif type == "reboot":
+ if self.__doShutdown("reboot"):
+ self.hdf["Data.Success"] = "Plugins.shutdown.Reboot"
+ self.hdf["Data.Redirect.URL"] = ""
+ self.hdf["Data.Redirect.Delay"] = REDIRECT_DELAY
+ return None
+ else:
+ self.hdf["Data.Warning"] = "Plugins.shutdown.RebootFailed"
+ return "form_shutdown"
+ else:
+ return "form_shutdown"
+
+
+ def getStatus(self):
+ return "the box is up'n'running"
+
+
+ def __doShutdown(self, action):
+ import subprocess
+ import os
+ proc = subprocess.Popen(
+ shell = False,
+ args = [
+ self.cbox.prefs["Programs"]["super"],
+ self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
+ "plugin",
+ os.path.join(self.pluginDir, "root_action.py"),
+ action])
+ proc.communicate()
+ return proc.returncode == 0
+
diff --git a/pythonrewrite/plugins/volume_details/lang/en.hdf b/pythonrewrite/plugins/volume_details/lang/en.hdf
new file mode 100644
index 0000000..f6c81ac
--- /dev/null
+++ b/pythonrewrite/plugins/volume_details/lang/en.hdf
@@ -0,0 +1,21 @@
+Name = Technical details of a volume
+Link = Details
+Rank = 100
+
+Title.Details = Technical details
+
+Text {
+ DeviceName = Name of device
+ Status = Status
+ StatusActive = active
+ StatusPassive = passive
+ EncryptionStatus = Encryption
+ Yes = Yes
+ No = No
+ Size {
+ All = Space of volume
+ Avail = Available space of volume
+ Used = Used space of volume
+ }
+}
+
diff --git a/pythonrewrite/plugins/volume_details/volume_details.cs b/pythonrewrite/plugins/volume_details/volume_details.cs
new file mode 100644
index 0000000..0022d14
--- /dev/null
+++ b/pythonrewrite/plugins/volume_details/volume_details.cs
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
:
+
:
+
:
+
:
+
+
:
+
:
+
: %
+
+
+
+
diff --git a/pythonrewrite/plugins/volume_details/volume_details.py b/pythonrewrite/plugins/volume_details/volume_details.py
new file mode 100644
index 0000000..7354639
--- /dev/null
+++ b/pythonrewrite/plugins/volume_details/volume_details.py
@@ -0,0 +1,17 @@
+import CryptoBoxPlugin
+
+
+class volume_details(CryptoBoxPlugin.CryptoBoxPlugin):
+
+ pluginCapabilities = [ "volume" ]
+ requestAuth = False
+
+
+ def doAction(self):
+ ## all variables are already set somewhere else
+ return "volume_details"
+
+
+ def getStatus(self):
+ return "no status"
+
diff --git a/pythonrewrite/plugins/volume_mount/lang/en.hdf b/pythonrewrite/plugins/volume_mount/lang/en.hdf
new file mode 100644
index 0000000..4cc9c87
--- /dev/null
+++ b/pythonrewrite/plugins/volume_mount/lang/en.hdf
@@ -0,0 +1,57 @@
+Name = Mount and umount volumes
+Link = Main
+Rank = 0
+
+
+Title {
+ Mount = Activate volume
+ Umount = Deactivate volume
+}
+
+
+Button {
+ Mount = Activate volume
+ Umount = Deactivate volume
+}
+
+
+SuccessMessage {
+ MountDone {
+ Title = Encrypted filesystem activated
+ Text = The encrypted filesystem is now available.
+ }
+
+ UmountDone {
+ Title = Encrypted filesystem deactivated
+ Text = The encrypted filesystem is now secured from all forms of access.
+ }
+}
+
+
+WarningMessage {
+ MountFailed {
+ Title = Activation failed
+ Text = The encrypted filesystem could not be activated. Probably the given password was wrong. Please try again.
+ }
+
+ MountCryptoFailed {
+ Title = Activation failed
+ Text = Maybe you entered the wrong password?
+ }
+
+ UmountFailed {
+ Title = Deactivation failed
+ Text = The encrypted filesystem could not be deactivated. Probably some files are still in use. Close all unclean programs (for example that widely used word processor). In case of emergency just shut down the CryptoBox!
+ }
+
+ IsAlreadyMounted {
+ Title = Already active
+ Text = The volume is already active.
+ }
+
+ IsNotMounted {
+ Title = Inactive
+ Text = The volume is currently not active.
+ }
+
+}
diff --git a/pythonrewrite/plugins/volume_mount/volume_mount.cs b/pythonrewrite/plugins/volume_mount/volume_mount.cs
new file mode 100644
index 0000000..03ffad0
--- /dev/null
+++ b/pythonrewrite/plugins/volume_mount/volume_mount.cs
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/pythonrewrite/plugins/volume_props/lang/en.hdf b/pythonrewrite/plugins/volume_props/lang/en.hdf
new file mode 100644
index 0000000..fbcd1d8
--- /dev/null
+++ b/pythonrewrite/plugins/volume_props/lang/en.hdf
@@ -0,0 +1,51 @@
+Name = Volume properties
+Link = Properties
+Rank = 40
+
+Title {
+ Properties = Properties
+ ChangeVolumeName = Change the name of this volume
+ ChangePassword = Change the password of this volume
+}
+
+
+Button {
+ ContainerNameSet = Change name
+ ChangePassword = Change password
+}
+
+
+Text {
+ UmountBeforeProps = You must deactivate a volume, if you want to change its properties.
+}
+
+
+SuccessMessage {
+ PasswordChange {
+ Title = Password changed
+ Text = The password of this volume was changed successfully.
+ }
+}
+
+
+WarningMessage {
+ InvalidVolumeName {
+ Title = Changing of container's name failed
+ Text = The supplied new name of the container was invalid. Please try again!
+ }
+
+ SetVolumeNameFailed {
+ Title = Changing of container's name failed
+ Text = Could not change the name of the container. Take a look at the log files for details.
+ }
+
+ VolumeNameIsInUse {
+ Title = Volume name is in use
+ Text = Another volume with the same name is active.
+ }
+
+ PasswordChange {
+ Title = Could not change password
+ Text = The password of this volume could not be changed - sorry!
+ }
+}
diff --git a/pythonrewrite/plugins/volume_props/volume_properties.cs b/pythonrewrite/plugins/volume_props/volume_properties.cs
new file mode 100644
index 0000000..b6f3d71
--- /dev/null
+++ b/pythonrewrite/plugins/volume_props/volume_properties.cs
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+