broken interface fixed in 'partition' plugin for ie
rendering bug of volume_properties fixed for ie fixed screen width in a mozilla/ie compatible way added german translation: 'log', 'network', 'volume_automount' and 'volume_details' fixed config management of 'plugin_manager' plugin fixed filtering of log level messages for 'logs' plugin updated documentation for ssl configurations changed default installation destinations in setup.py added nice background images to environment and help messages replaced message 'div' with 'fieldset' moved stylesheet data of plugins to html header (as required by spec) removed obsolete css definitions removed obsolete old perl/bash code improved 'update_po_files': remove obsolete msgids functionality of 'update_english.sh' moved to 'update_po_files' omit 'weblang' link attribute if it does not change the default setting changed default language from 'de' to 'en' fixed template bug that prevented the translation of plugin links fixed invalid html implement filecheck overriding for unittestsmaster
parent
52dd35e7b4
commit
794998f950
@ -1,37 +0,0 @@
|
||||
# Makefile to compile the binary suid-wrapper for cryptobox
|
||||
#
|
||||
# LIB_DIR should be defined in the higher level Makefile
|
||||
#
|
||||
|
||||
HEADER_FILE = cryptobox_wrapper.h
|
||||
SRC_FILE = cryptobox_wrapper.c
|
||||
CGI_SUID_FILE = cryptobox_cgi_wrapper
|
||||
ROOT_SUID_FILE = cryptobox_root_wrapper
|
||||
|
||||
CGI_FILENAME = cryptobox.pl
|
||||
ROOT_SCRIPT_FILENAME = cbox-root-actions.sh
|
||||
# fall back to default, if not overwritten
|
||||
LIB_DIR = /usr/local/lib/cryptobox
|
||||
|
||||
|
||||
# _always_ recompile (in case of a changed LIB_DIR)
|
||||
.PHONY: build clean $(CGI_SUID_FILE) $(ROOT_SUID_FILE)
|
||||
|
||||
build: $(CGI_SUID_FILE) $(ROOT_SUID_FILE)
|
||||
|
||||
|
||||
$(CGI_SUID_FILE): $(SRC_FILE)
|
||||
@echo '#define EXEC_PATH "$(LIB_DIR)/$(CGI_FILENAME)"' >$(HEADER_FILE)
|
||||
$(CC) -o $(CGI_SUID_FILE) $(SRC_FILE)
|
||||
-rm $(HEADER_FILE)
|
||||
|
||||
|
||||
$(ROOT_SUID_FILE): $(SRC_FILE)
|
||||
@echo '#define EXEC_PATH "$(LIB_DIR)/$(ROOT_SCRIPT_FILENAME)"' >$(HEADER_FILE)
|
||||
$(CC) -o $(ROOT_SUID_FILE) $(SRC_FILE)
|
||||
-rm $(HEADER_FILE)
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f $(CGI_SUID_FILE) $(ROOT_SUID_FILE) $(HEADER_FILE)
|
||||
|
@ -1,474 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 02005 sense.lab <senselab@systemausfall.org>
|
||||
#
|
||||
# License: This script is distributed under the terms of version 2
|
||||
# of the GNU GPL. See the LICENSE file included with the package.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# this script does EVERYTHING
|
||||
# all other scripts are only frontends :)
|
||||
#
|
||||
# called by:
|
||||
# - some rc-scripts
|
||||
# - the web frontend cgi
|
||||
#
|
||||
|
||||
# TODO: check permissions and owners of config files, directories and scripts before
|
||||
# running cbox-root-actions.sh
|
||||
|
||||
set -eu
|
||||
|
||||
|
||||
# default location of config file
|
||||
CONF_FILE=/etc/cryptobox/cryptobox.conf
|
||||
|
||||
LIB_DIR=$(dirname "$0")
|
||||
|
||||
# to determine a nice default partition name
|
||||
DEVICE_NAME_PREFIX="Disk #"
|
||||
|
||||
# read the default setting file, if it exists
|
||||
test -e /etc/default/cryptobox && . /etc/default/cryptobox
|
||||
|
||||
test ! -e "$CONF_FILE" && echo "Could not find the configuration file: $CONF_FILE" >&2 && exit 1
|
||||
|
||||
# parse config file
|
||||
. "$CONF_FILE"
|
||||
|
||||
test ! -e "$CONF_FILE" && echo "Could not find the distribution specific configuration file: $CONF_FILE" >&2 && exit 1
|
||||
|
||||
# parse the distribution specific file
|
||||
. "$DISTRIBUTION_CONF"
|
||||
|
||||
# check for writable log file
|
||||
test -w "$LOG_FILE" || LOG_FILE=/tmp/$(basename "$LOG_FILE")
|
||||
|
||||
# retrieve configuration directory
|
||||
CONFIG_DIR="$(getent passwd $CRYPTOBOX_USER | cut -d ':' -f 6)/config"
|
||||
CONFIG_MARKER=cryptobox.marker
|
||||
|
||||
## configuration
|
||||
ROOT_PERM_SCRIPT="$LIB_DIR/cryptobox_root_wrapper"
|
||||
# ROOT_PERM_SCRIPT needs the MNT_PARENT setting
|
||||
export MNT_PARENT="$(cd ~; pwd)/mnt"
|
||||
|
||||
######## stuff ##########
|
||||
|
||||
# all partitions with a trailing number
|
||||
ALL_PARTITIONS=$(cat /proc/partitions | sed '1,2d; s/ */ /g; s/^ *//' | cut -d " " -f 4 | grep '[0-9]$')
|
||||
|
||||
#########################
|
||||
|
||||
function log_msg()
|
||||
{
|
||||
# the log file is (maybe) not writable during boot - try
|
||||
# before writing ...
|
||||
test -w "$LOG_FILE" || return 0
|
||||
echo >>"$LOG_FILE"
|
||||
echo "##### `date` #####" >>"$LOG_FILE"
|
||||
echo "$1" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
|
||||
function error_msg()
|
||||
# parameters: ExitCode ErrorMessage
|
||||
{
|
||||
local all=$@
|
||||
test $# -ne 2 && error_msg 1 "*** invalid call of error_msg *** $all"
|
||||
echo "[`date`] - $2" | tee -a "$LOG_FILE" >&2
|
||||
# print the execution stack - not usable with busybox
|
||||
# caller | sed 's/^/\t/' >&2
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: device
|
||||
function is_device_allowed() {
|
||||
# check for invalid characters and exit if one is found
|
||||
local device=$(echo "$1" | sed 's#[^a-zA-Z0-9_\-\./]##g')
|
||||
test "$1" = "$device" || return 1
|
||||
# remove leading "/dev/"
|
||||
device=$(echo "$device" | sed 's#^/dev/##')
|
||||
# return for empty name
|
||||
test -z "$device" && return 1
|
||||
for a in $ALL_PARTITIONS
|
||||
do echo "$device" | grep -q "^$a.*" && return 0
|
||||
done
|
||||
# no matching device found - exit with error
|
||||
return 1
|
||||
}
|
||||
|
||||
function config_set_value()
|
||||
# parameters: SettingName [SettingValue]
|
||||
# read from stdin if SettingValue is not defined
|
||||
{
|
||||
if test $# -gt 1
|
||||
then echo "$2" > "$CONFIG_DIR/$1"
|
||||
else cat - >"$CONFIG_DIR/$1"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function config_get_value()
|
||||
# parameters: SettingName
|
||||
{
|
||||
# use mounted config, if it exists - otherwise use defaults
|
||||
local conf_dir
|
||||
test -z "$1" && error_msg 1 "empty setting name"
|
||||
# check for existence - maybe use default values (even for old
|
||||
# releases that did not contain this setting)
|
||||
if test -e "$CONFIG_DIR/$1"
|
||||
then cat "$CONFIG_DIR/$1"
|
||||
elif test -e "$CONFIG_DEFAULTS_DIR/$1"
|
||||
then cat "$CONFIG_DEFAULTS_DIR/$1"
|
||||
else case "$1" in
|
||||
# you may place default values for older versions here
|
||||
# for compatibility
|
||||
* )
|
||||
error_msg 2 "unknown configuration value ($1)"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
function list_partitions_of_type()
|
||||
# parameter: { config | crypto | plaindata | unused }
|
||||
{
|
||||
local config=
|
||||
local crypto=
|
||||
local plaindata=
|
||||
local unused=
|
||||
for a in $ALL_PARTITIONS
|
||||
do if "$ROOT_PERM_SCRIPT" is_crypto_partition "/dev/$a"
|
||||
then crypto="$crypto /dev/$a"
|
||||
elif "$ROOT_PERM_SCRIPT" is_config_partition "/dev/$a"
|
||||
then config="$config /dev/$a"
|
||||
elif "$ROOT_PERM_SCRIPT" is_plaindata_partition "/dev/$a"
|
||||
then plaindata="$plaindata /dev/$a"
|
||||
else unused="$unused /dev/$a"
|
||||
fi
|
||||
done
|
||||
case "$1" in
|
||||
config )
|
||||
echo "$config"
|
||||
;;
|
||||
crypto )
|
||||
echo "$crypto"
|
||||
;;
|
||||
plaindata )
|
||||
echo "$plaindata"
|
||||
;;
|
||||
unused )
|
||||
echo "$unused"
|
||||
;;
|
||||
* )
|
||||
error_msg 11 "wrong parameter ($1) for list_partition_types in $(basename $0)"
|
||||
;;
|
||||
esac | tr " " "\n" | grep -v '^$'
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function get_device_mnt_name() {
|
||||
"$ROOT_PERM_SCRIPT" get_device_mnt_name "$1"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function get_device_uuid() {
|
||||
"$ROOT_PERM_SCRIPT" get_device_uuid "$1"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
# return the readable name of the crypto container, if it is already defined
|
||||
# if undefined - return the uuid
|
||||
function get_device_name() {
|
||||
local uuid=$(get_device_uuid "$1")
|
||||
local dbname=$(config_get_value "names.db" | grep "^$uuid:" | cut -d ":" -f 2-)
|
||||
# return dbname if it exists
|
||||
test -n "$dbname" && echo "$dbname" && return 0
|
||||
# find a nice name for the new partition
|
||||
local counter=1
|
||||
local test_name
|
||||
local test_uuid
|
||||
local test_result
|
||||
# try to find a name with the defined "prefix" followed by a number ...
|
||||
while true
|
||||
do test_name="$DEVICE_NAME_PREFIX$counter"
|
||||
if config_get_value "names.db" | grep -q ":$test_name$"
|
||||
then counter=$((counter+1))
|
||||
else # save it for next time
|
||||
set_device_name "$1" "$test_name"
|
||||
echo "$test_name"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
function set_device_name()
|
||||
# TODO: the implementation is quite ugly, but it works (tm)
|
||||
# Parameter: DEVICE NAME
|
||||
{
|
||||
local uuid=$(get_device_uuid "$1")
|
||||
# remove the old setting for this device and every possible entry with the same name
|
||||
local new_config=$(config_get_value 'names.db' | sed "/^$uuid:/d; /^[^:]*:$2$/d"; echo "$uuid:$2")
|
||||
echo "$new_config" | config_set_value "names.db"
|
||||
}
|
||||
|
||||
|
||||
function does_crypto_name_exist()
|
||||
# Parameter: NAME
|
||||
{
|
||||
config_get_value 'names.db' | grep -q "^[^:]*:$1$"
|
||||
}
|
||||
|
||||
|
||||
function create_crypto()
|
||||
# Parameter: DEVICE NAME KEYFILE
|
||||
# keyfile is necessary, to allow background execution via 'at'
|
||||
{
|
||||
local device=$1
|
||||
local name=$2
|
||||
local keyfile=$3
|
||||
# otherwise the web interface will hang
|
||||
# passphrase may be passed via command line
|
||||
local key=$(<"$keyfile")
|
||||
# remove the passphrase-file as soon as possible
|
||||
dd if=/dev/zero of="$keyfile" bs=512 count=1 2>/dev/null
|
||||
rm "$keyfile"
|
||||
|
||||
log_msg "Creating crypto partition with the cipher $DEFAULT_CIPHER on $device"
|
||||
echo "$key" | "$ROOT_PERM_SCRIPT" create_crypto "$device"
|
||||
|
||||
set_crypto_name "$device" "$name"
|
||||
}
|
||||
|
||||
|
||||
function is_config_active() {
|
||||
test -f "$CONFIG_DIR/$CONFIG_MARKER"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function is_mounted() {
|
||||
local name=$(get_device_mnt_name "$1")
|
||||
test -n "$name" && mountpoint -q "$MNT_PARENT/$name"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function is_plain() {
|
||||
"$ROOT_PERM_SCRIPT" is_plain_partition "$1"
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function is_encrypted() {
|
||||
"$ROOT_PERM_SCRIPT" is_crypto_partition "$1"
|
||||
}
|
||||
|
||||
|
||||
# list which allowed disks are at the moment connected with the cbox
|
||||
function get_available_disks() {
|
||||
for scan in $SCAN_DEVICES
|
||||
do for avail in $ALL_PARTITIONS
|
||||
do echo "$avail" | grep -q "^$scan[^/]*" && echo "/dev/$avail"
|
||||
done
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Parameter: DEVICE
|
||||
function mount_crypto() {
|
||||
local device=$1
|
||||
test -z "$device" && error_msg 4 'No valid harddisk found!'
|
||||
is_mounted "$device" && echo "The crypto filesystem is already active!" && return
|
||||
# passphrase is read from stdin
|
||||
log_msg "Mounting a crypto partition from $device"
|
||||
"$ROOT_PERM_SCRIPT" mount "$device" >>"$LOG_FILE" 2>&1
|
||||
}
|
||||
|
||||
|
||||
function umount_partition() {
|
||||
# Parameter: device
|
||||
local container=$(get_device_name "$1")
|
||||
"$ROOT_PERM_SCRIPT" umount "$1"
|
||||
}
|
||||
|
||||
|
||||
function box_purge()
|
||||
# removing just the first bytes from the harddisk should be enough
|
||||
# every harddisk will be overriden!
|
||||
# this feature is only useful for validation
|
||||
{
|
||||
# TODO: not ALL harddisks, please!
|
||||
get_available_disks | while read a
|
||||
do log_msg "Purging $a ..."
|
||||
"$ROOT_PERM_SCRIPT" trash_device "$a"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
function turn_off_all_containers() {
|
||||
# TODO - needs to be implemented
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
### main ###
|
||||
|
||||
# set PATH because thttpd removes /sbin and /usr/sbin for cgis
|
||||
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
|
||||
ACTION=help
|
||||
test $# -gt 0 && ACTION=$1 && shift
|
||||
|
||||
case "$ACTION" in
|
||||
crypto-up )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'crypto-up'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
mount_crypto "$1"
|
||||
;;
|
||||
crypto-down )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'crypto-down'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
umount_partition "$1"
|
||||
;;
|
||||
init )
|
||||
init_cryptobox </dev/null >>"$LOG_FILE" 2>&1
|
||||
;;
|
||||
list_container )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'list_container'"
|
||||
case "$1" in
|
||||
config | unused | plaindata | crypto )
|
||||
list_partitions_of_type "$1"
|
||||
;;
|
||||
* )
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
;;
|
||||
get_device_name )
|
||||
# Parameter: DEVICE
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'get_device_name'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
get_device_name "$1"
|
||||
;;
|
||||
set_device_name )
|
||||
# Parameter: DEVICE NAME
|
||||
test $# -ne 2 && error_msg 10 "invalid number of parameters for 'set_device_name'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
set_device_name "$1" "$2"
|
||||
;;
|
||||
device_init )
|
||||
# Parameter: DEVICE [KEYFILE]
|
||||
test $# -lt 1 && error_msg 10 "invalid number of parameters for 'device_init' ($@)"
|
||||
test $# -gt 2 && error_msg 10 "invalid number of parameters for 'device_init' ($@)"
|
||||
if test $# -eq 2
|
||||
then test -z "$2" -o ! -e "$2" && error_msg 11 "invalid keyfile ($2) given for 'device_init'"
|
||||
fi
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
if test $# -eq 2
|
||||
then "$ROOT_PERM_SCRIPT" create_crypto "$1" "$2"
|
||||
else "$ROOT_PERM_SCRIPT" create_plain "$1"
|
||||
fi
|
||||
true
|
||||
;;
|
||||
is_mounted )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'is_mounted'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
is_mounted "$1"
|
||||
;;
|
||||
is_encrypted )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'is_encrypted'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
is_encrypted "$1"
|
||||
;;
|
||||
is_plain )
|
||||
test $# -ne 1 && error_msg 10 "invalid number of parameters for 'is_plain'"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
is_plain "$1"
|
||||
;;
|
||||
check_config)
|
||||
is_config_active
|
||||
;;
|
||||
get_available_disks )
|
||||
get_available_disks
|
||||
;;
|
||||
set_config )
|
||||
test $# -ne 2 && error_msg 7 "'set_config' requires two parameters"
|
||||
config_set_value "$1" "$2"
|
||||
;;
|
||||
get_config )
|
||||
test $# -ne 1 && error_msg 6 "'get_config' requires exactly one parameter"
|
||||
config_get_value "$1"
|
||||
;;
|
||||
get_capacity_info )
|
||||
test $# -ne 1 && error_msg 6 "'get_capacity_info' requires exactly one parameter"
|
||||
is_device_allowed "$1" || error_msg 12 "invalid device: $1"
|
||||
is_mounted "$1" || error_msg 13 "the device is not mounted: $1"
|
||||
name=$(get_device_mnt_name "$1")
|
||||
df -h "$MNT_PARENT/$name" | tail -1
|
||||
;;
|
||||
diskinfo )
|
||||
get_available_disks | while read a
|
||||
do "$ROOT_PERM_SCRIPT" diskinfo "$a"
|
||||
done 2>/dev/null
|
||||
;;
|
||||
box-purge )
|
||||
log_msg "Cleaning the CryptoBox ..."
|
||||
turn_off_all_containers
|
||||
"$0" config-down
|
||||
box_purge >>"$LOG_FILE" 2>&1
|
||||
;;
|
||||
poweroff )
|
||||
log_msg "Shutting down the Cryptobox ..."
|
||||
turn_off_all_containers
|
||||
"$ROOT_PERM_SCRIPT" poweroff
|
||||
;;
|
||||
reboot )
|
||||
log_msg "Rebooting the Cryptobox ..."
|
||||
turn_off_all_containers
|
||||
"$ROOT_PERM_SCRIPT" reboot
|
||||
;;
|
||||
umount_all )
|
||||
log_msg "Unmounting all volumes ..."
|
||||
turn_off_all_containers
|
||||
;;
|
||||
* )
|
||||
echo "[$(basename $0)] - unknown action: $ACTION" >&2
|
||||
echo "Syntax: $(basename $0) ACTION [PARAMS]"
|
||||
echo " crypto-up - mount crypto partition"
|
||||
echo " crypto-down - unmount crypto partition"
|
||||
echo " crypto-create - a wrapper for 'crypto-create-bg'"
|
||||
echo " crypto-create-bg - create encrypted blockdevice and run mkfs"
|
||||
echo " is_mounted - check, if crypto partition is mounted"
|
||||
echo " check_config - check, if the configuration is usable"
|
||||
echo " get_available_disks - shows all accessible disks"
|
||||
echo " get_current_ip - get the current IP of the network interface"
|
||||
echo " set_config NAME VALUE - change a configuration setting"
|
||||
echo " get_config NAME - retrieve a configuration setting"
|
||||
echo " get_device_name DEVICE - retrieve the human readable name of a partition"
|
||||
echo " set_device_name DEVICE - set the human readable name of a partition"
|
||||
echo " device_init DEVICE KEYFILE - initialize the filesystem of a partition (the keyfile just contains the passphrase)"
|
||||
echo " get_capacity_info - print the output of 'df' for the (mounted) partition"
|
||||
echo " diskinfo - show the partition table of the harddisk"
|
||||
echo " box-purge - destroy the partition tables of all harddisks (delete everything)"
|
||||
echo " poweroff - turn off the computer"
|
||||
echo " reboot - reboot the computer"
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
@ -1,341 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 02005 sense.lab <senselab@systemausfall.org>
|
||||
#
|
||||
# License: This script is distributed under the terms of version 2
|
||||
# of the GNU GPL. See the LICENSE file included with the package.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# this script is responsible for all dangerous actions, that require root privileges
|
||||
# every action should be checked at least TWICE a day for open holes :)
|
||||
# usually will get call via sudo
|
||||
#
|
||||
# called by:
|
||||
# - cbox-manage.sh
|
||||
#
|
||||
|
||||
set -eu
|
||||
|
||||
LIB_DIR=$(dirname "$0")
|
||||
LIB_DIR=$(cd "$LIB_DIR"; pwd)
|
||||
|
||||
test "$(id -u)" -ne 0 && echo "$(basename $0) - only root may call this script" >&2 && exit 100
|
||||
|
||||
# read the default setting file, if it exists
|
||||
test -e /etc/default/cryptobox && . /etc/default/cryptobox
|
||||
|
||||
# set CONF_FILE to default value, if not configured in /etc/default/cryptobox
|
||||
CONF_FILE=${CONF_FILE:-/etc/cryptobox/cryptobox.conf}
|
||||
# parse config file
|
||||
. "$CONF_FILE"
|
||||
# parse distribution specific file
|
||||
. "$DISTRIBUTION_CONF"
|
||||
|
||||
CB_SCRIPT="$LIB_DIR/cbox-manage.sh"
|
||||
CONFIG_MARKER=cryptobox.marker
|
||||
|
||||
|
||||
############ some useful functions ###############
|
||||
|
||||
# check if the given device is part of the SCAN_DEVICE list
|
||||
# every entry in SCAN_DEVICES is matched as "^/dev/${SCAN_DEVICE}[^/]*$" against
|
||||
# the given device
|
||||
# other devices may not be touched
|
||||
function is_device_allowed()
|
||||
# parameter: device
|
||||
{
|
||||
for a in $SCAN_DEVICES
|
||||
do echo "$1" | grep -q "^/dev/${a}[^/]*$" && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# return the uuid of the partition (if possible)
|
||||
# this works at least for luks, ext2/3 and vfat partitions
|
||||
function get_device_uuid() {
|
||||
local UUID
|
||||
# check for luksUUID or ext2/3-uuid
|
||||
if is_luks_device "$1"
|
||||
then UUID=$("$CRYPTSETUP" luksUUID "$1")
|
||||
else test -x "$BLKID" && UUID=$("$BLKID" -s UUID -o value -c /dev/null -w /dev/null "$1" 2>/dev/null)
|
||||
fi
|
||||
if test -z "$UUID"
|
||||
then get_device_flat_name "$1"
|
||||
else echo "$UUID"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# the device name is "flattened"
|
||||
function get_device_flat_name() {
|
||||
echo "$1" | sed 's#/#_#g'
|
||||
}
|
||||
|
||||
|
||||
# the basename of the mountpoint for this device - should be somehow human_readable
|
||||
function get_device_mnt_name() {
|
||||
"$CB_SCRIPT" get_device_name "$1"
|
||||
}
|
||||
|
||||
|
||||
# every devmapper name should look like a UUID
|
||||
function is_uuid_valid() {
|
||||
local hex=[0-9a-f]
|
||||
echo "$1" | grep -q "^$hex\{8\}-$hex\{4\}-$hex\{4\}-$hex\{4\}-$hex\{12\}$"
|
||||
}
|
||||
|
||||
|
||||
# parameter ExitCode ErrorMessage
|
||||
function error_msg() {
|
||||
echo "CBOX-ERROR: [$(basename $0) - $ACTION] - $2" >&2
|
||||
exit $1
|
||||
}
|
||||
|
||||
|
||||
# parameter: device sfdisk_layout_setup
|
||||
# e.g.: /dev/hda "0,1,L \n,,L\n"
|
||||
function partition_device() {
|
||||
# TODO: allow different layouts
|
||||
# TODO: skip config partition if a configuration is already active
|
||||
# sfdisk -n doesn't actually write (for testing purpose)
|
||||
if echo -e "$2" | "$SFDISK" -n "$1"
|
||||
then echo -e "$2" | "$SFDISK" "$1" || return 1
|
||||
else return 2
|
||||
fi
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
function is_luks_device()
|
||||
# parameter: device
|
||||
{
|
||||
"$CRYPTSETUP" isLuks "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
|
||||
################ main ####################
|
||||
|
||||
ACTION=unknown
|
||||
test $# -gt 0 && ACTION=$1 && shift
|
||||
|
||||
|
||||
case "$ACTION" in
|
||||
partition_disk )
|
||||
test $# -ne 2 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
partition_device "$1" "$2" || \
|
||||
error_msg 2 "failed to create new partition table on device $1"
|
||||
;;
|
||||
mount )
|
||||
# parameters: device
|
||||
# returns the relative name of the mointpoint for success
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
mnt_name=$(get_device_mnt_name "$1")
|
||||
mountpoint -q "$MNT_PARENT/$mnt_name" && \
|
||||
error_msg 5 "a device with the same name ($mnt_name) is already mounted"
|
||||
mkdir -p "$MNT_PARENT/$mnt_name"
|
||||
if is_luks_device "$1"
|
||||
then "$CRYPTSETUP" luksOpen "$1" "$mnt_name" || \
|
||||
error_msg 6 "could not open encrypted device $1"
|
||||
if mount "$DEV_MAPPER_DIR/$mnt_name" "$MNT_PARENT/$mnt_name"
|
||||
then true
|
||||
else "$CRYPTSETUP" luksClose "$mnt_name" || true
|
||||
error_msg 7 "wrong password for $1 supplied"
|
||||
fi
|
||||
else mount "$1" "$MNT_PARENT/$mnt_name" || \
|
||||
error_msg 8 "invalid filesystem on device $1"
|
||||
fi
|
||||
# just in case, that there is no ext2/3 filesystem:
|
||||
# set uid option (will fail silently for ext2/3)
|
||||
# TODO: there is no FILE_USER setting anymore - do we still need it?
|
||||
#mount -o remount,uid="$FILE_USER" "$MNT_PARENT/$name" 2>/dev/null || true
|
||||
# adapt top-level permission to current setup - again: may fail silently
|
||||
#chown "$FILE_USER" "$MNT_PARENT/$name" 2>/dev/null || true
|
||||
true
|
||||
;;
|
||||
umount )
|
||||
#parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
mnt_name=$(get_device_mnt_name "$1")
|
||||
mountpoint -q "$MNT_PARENT/$mnt_name" || \
|
||||
error_msg 9 "the device ($1) is not mounted as '$mnt_name'"
|
||||
# try to unmount - do it in lazy mode
|
||||
umount -l "$MNT_PARENT/$mnt_name"
|
||||
# TODO: check, what happens, if there are open files - does the device gets mapping removed?
|
||||
# remove (if necessary) the device mapping
|
||||
if test -e "$DEV_MAPPER_DIR/$mnt_name"
|
||||
then "$CRYPTSETUP" luksClose "$mnt_name" || \
|
||||
error_msg 11 "could not remove the device mapper ($mnt_name) for device $1"
|
||||
fi
|
||||
# try to remove the mountpoint - a failure is not important
|
||||
rmdir "$MNT_PARENT/$mnt_name" || true
|
||||
# set exitcode
|
||||
mountpoint -q "$MNT_PARENT/$mnt_name" && exit 1
|
||||
true
|
||||
;;
|
||||
create_crypto )
|
||||
# parameter: device keyfile
|
||||
test $# -ne 2 && error_msg 1 "wrong number of parameters"
|
||||
keyfile=$2
|
||||
test -e "$keyfile" || error_msg 2 "keyfile ($keyfile) not found"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
# read the passphrase from stdin
|
||||
# the iter-time is in milliseconds - keep it low for fast mounting
|
||||
cat "$keyfile" | \
|
||||
"$CRYPTSETUP" --cipher "$DEFAULT_CIPHER" --iter-time 2000 --batch-mode luksFormat "$1" || \
|
||||
error_msg 11 "failed to create the encrypted partition"
|
||||
name=$(get_device_mnt_name "$1")
|
||||
cat "$keyfile" | "$CRYPTSETUP" --batch-mode luksOpen "$1" "$name" || \
|
||||
error_msg 12 "failed to open the encrypted partition"
|
||||
# trash the passphrase in keyfile
|
||||
echo "0123456789abcdefghijklmnopqrstuvwxyz" > "$keyfile"
|
||||
# the disk cache surely prevents the previous line from being written, but we do it anyway ...
|
||||
echo "zyxwvutsrqponmlkjihgfedcba9876543210" > "$keyfile"
|
||||
rm "$keyfile"
|
||||
# complete in background
|
||||
(
|
||||
"$MKFS_DATA" "$DEV_MAPPER_DIR/$name" || \
|
||||
error_msg 13 "failed to create the encrypted filesystem"
|
||||
"$CRYPTSETUP" --batch-mode luksClose "$name" || \
|
||||
error_msg 14 "failed to close the encrypted mapped device"
|
||||
) </dev/null >/dev/null 2>/dev/null &
|
||||
true
|
||||
;;
|
||||
create_plain )
|
||||
# parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters for 'create_plain'"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
# complete in background
|
||||
(
|
||||
"$MKFS_DATA" "$1" || \
|
||||
error_msg 15 "failed to create the plaintext filesystem"
|
||||
) </dev/null >/dev/null 2>/dev/null &
|
||||
true
|
||||
;;
|
||||
get_device_mnt_name )
|
||||
# parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
get_device_mnt_name "$1"
|
||||
;;
|
||||
get_device_uuid )
|
||||
# parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
get_device_uuid "$1"
|
||||
;;
|
||||
is_config_partition )
|
||||
# parameter: device
|
||||
# returns exitcode 0 if the device contains a configuration
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
is_config=0
|
||||
tmp_dir=/tmp/$(basename $0)-$$-mnt
|
||||
mkdir -p "$tmp_dir"
|
||||
# error means "no config partition"
|
||||
if mount "$1" "$CONFIG_DIR"
|
||||
then test -e "$CONFIG_DIR/$CONFIG_MARKER" && is_config=1
|
||||
umount "$CONFIG_DIR" || \
|
||||
error_msg 14 "unable to unmount configation partition after probing"
|
||||
fi
|
||||
rmdir "$tmp_dir" || true
|
||||
# return 0 if $device is a config partition
|
||||
test "$is_config" -eq 1 && exit 0
|
||||
exit 1
|
||||
;;
|
||||
is_crypto_partition )
|
||||
# parameter: device
|
||||
# returns exitcode 0 if the device contains a luks header
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
is_luks_device "$1"
|
||||
;;
|
||||
is_plain_partition )
|
||||
# parameter: device
|
||||
# returns exitcode 0 if the device contains a readable filesystem
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
status=0
|
||||
tmp_dir=/tmp/$(basename $0)-$$-mnt
|
||||
mkdir -p "$tmp_dir"
|
||||
if mount "$1" "$tmp_dir" >/dev/null 2>/dev/null
|
||||
then test ! -e "$tmp_dir/$CONFIG_MARKER" && status=1
|
||||
umount "$tmp_dir"
|
||||
fi
|
||||
rmdir "$tmp_dir" || true
|
||||
test "$status" -eq 1 && exit 0
|
||||
exit 1
|
||||
;;
|
||||
trash_device )
|
||||
# parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
dd if=/dev/urandom of="$1" bs=512 count=1 2>/dev/null
|
||||
;;
|
||||
diskinfo )
|
||||
# parameter: device
|
||||
test $# -ne 1 && error_msg 1 "wrong number of parameters"
|
||||
is_device_allowed "$1" || \
|
||||
error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)"
|
||||
"$SFDISK" -L -q -l "$1"
|
||||
;;
|
||||
update_network )
|
||||
# parameter: none
|
||||
ip=
|
||||
# TODO: can we avoid to hard-code the filename ($CONFIG_DIR/ip) here?
|
||||
test -e "$CONFIG_DIR/ip" && ip=$(<"$CONFIG_DIR/ip")
|
||||
test -n "$z" && ifconfig "$NET_IFACE" "$ip"
|
||||
;;
|
||||
poweroff )
|
||||
# TODO: check configuration setting before
|
||||
"$POWEROFF"
|
||||
;;
|
||||
reboot )
|
||||
# TODO: check configuration setting before
|
||||
"$REBOOT"
|
||||
;;
|
||||
* )
|
||||
echo "[$(basename $0)] - unknown action: $ACTION" >&2
|
||||
echo "Syntax: $(basename $0) ACTION PARAMETERS"
|
||||
echo ' partition_disk $device $disk_layout'
|
||||
echo ' get_device_name $device'
|
||||
echo ' get_device_uuid $device'
|
||||
echo ' create_crypto $device'
|
||||
echo ' mount $device'
|
||||
echo ' umount $name'
|
||||
echo ' create_config $device'
|
||||
echo ' mount_config $device'
|
||||
echo ' remount_config { ro | rw }'
|
||||
echo ' umount_config'
|
||||
echo ' is_config_partition $device'
|
||||
echo ' is_plain_partition $device'
|
||||
echo ' is_crypto_partition $device'
|
||||
echo ' trash_device $device'
|
||||
echo ' diskinfo $device'
|
||||
echo ' update_network'
|
||||
echo ' poweroff'
|
||||
echo ' reboot'
|
||||
echo ' help'
|
||||
echo
|
||||
test "$ACTION" = "help" && exit 0
|
||||
# return error for any unknown/unspecified action
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -1,946 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright (c) 02005 sense.lab <senselab@systemausfall.org>
|
||||
#
|
||||
# License: This script is distributed under the terms of version 2
|
||||
# of the GNU GPL. See the LICENSE file included with the package.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# the web interface of the CryptoBox
|
||||
#
|
||||
|
||||
|
||||
###############################################
|
||||
|
||||
use strict;
|
||||
use CGI;
|
||||
use ClearSilver;
|
||||
use ConfigFile;
|
||||
use English;
|
||||
use CGI::Carp;
|
||||
use IO::File;
|
||||
use POSIX;
|
||||
|
||||
use constant CRYPTOBOX_VERSION => 0.3;
|
||||
|
||||
# debug levels
|
||||
use constant DEBUG_NONE => 0;
|
||||
use constant DEBUG_ERROR => 1;
|
||||
use constant DEBUG_WARN => 2;
|
||||
use constant DEBUG_INFO => 3;
|
||||
|
||||
# drop privileges
|
||||
$UID = $EUID;
|
||||
$GID = $EGID;
|
||||
|
||||
# necessary for suid perl scripts (see 'man perlsec' for details)
|
||||
$ENV{'PATH'} = '/bin:/usr/bin';
|
||||
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
|
||||
|
||||
my $CONFIG_FILE = '/etc/cryptobox/cryptobox.conf';
|
||||
|
||||
my $pagedata;
|
||||
|
||||
my ($LANGUAGE_DIR, $DEFAULT_LANGUAGE, $HTML_TEMPLATE_DIR, $DOC_DIR);
|
||||
my ($CB_SCRIPT, $LOG_FILE, $IS_DEVEL, $STYLESHEET_URL, $DEBUG_LEVEL);
|
||||
|
||||
# get the directory of the cryptobox scripts/binaries and untaint it
|
||||
$CB_SCRIPT = $0;
|
||||
$CB_SCRIPT =~ m/^(.*)\/[^\/]*$/;
|
||||
$CB_SCRIPT = ($1)? "$1/cbox-manage.sh" : './cbox-manage.sh';
|
||||
|
||||
&fatal_error ("could not find configuration file ($CONFIG_FILE)") unless (-e $CONFIG_FILE);
|
||||
my $config = ConfigFile::read_config_file($CONFIG_FILE);
|
||||
|
||||
$LOG_FILE = $config->{LOG_FILE};
|
||||
$LANGUAGE_DIR = $config->{LANGUAGE_DIR};
|
||||
$DEFAULT_LANGUAGE = $config->{LANGUAGE};
|
||||
$HTML_TEMPLATE_DIR = $config->{HTML_TEMPLATE_DIR};
|
||||
$DOC_DIR = $config->{DOC_DIR};
|
||||
$IS_DEVEL = ( -e $config->{DEV_FEATURES_SCRIPT});
|
||||
$STYLESHEET_URL = $config->{STYLESHEET_URL};
|
||||
if (defined($config->{DEBUG_LEVEL})) {
|
||||
$DEBUG_LEVEL = $config->{DEBUG_LEVEL};
|
||||
} else {
|
||||
$DEBUG_LEVEL = DEBUG_ERROR; # default debug level
|
||||
}
|
||||
|
||||
my $query = new CGI;
|
||||
|
||||
#################### subs ######################
|
||||
|
||||
# for fatal errors without the chance of clearsilver-rendering
|
||||
sub fatal_error() {
|
||||
my $message = shift;
|
||||
|
||||
print "Content-Type: text/html\n\n";
|
||||
print "<html><head><title>CryptoBox</title></head>\n";
|
||||
print "<body>\n";
|
||||
print '<h1 align="center">' . $message . "</h1>\n";
|
||||
print "</body></html>\n";
|
||||
die "[CryptoBox]: $message";
|
||||
}
|
||||
|
||||
|
||||
sub debug_msg() {
|
||||
my ($level, $message) = @_;
|
||||
return 0 unless ($level >= $DEBUG_LEVEL);
|
||||
warn "[cryptobox]: $message";
|
||||
}
|
||||
|
||||
|
||||
sub load_hdf {
|
||||
my $hdf = ClearSilver::HDF->new();
|
||||
|
||||
my $fname = "$HTML_TEMPLATE_DIR/main.cs";
|
||||
&fatal_error ("Template directory is invalid ($fname not found)!") unless (-e "$fname");
|
||||
$hdf->setValue("Settings.TemplateDir","$HTML_TEMPLATE_DIR");
|
||||
|
||||
&fatal_error ("Documentation directory ($DOC_DIR) not found!") unless (-d "$DOC_DIR");
|
||||
$hdf->setValue("Settings.DocDir","$DOC_DIR");
|
||||
|
||||
# if it was requested as directory index (link from index.html), we should
|
||||
# set a real script name - otherwise links with a query string will break
|
||||
# ignore POST part of the SCRIPT_NAME (after "&")
|
||||
(my $script_url = $ENV{'SCRIPT_NAME'}) =~ m/^[^&]*/;
|
||||
$hdf->setValue("ScriptName", ($ENV{'SCRIPT_NAME'} eq '/')? '/cryptobox' : $script_url );
|
||||
|
||||
# set stylesheet url
|
||||
$hdf->setValue("Settings.Stylesheet",$STYLESHEET_URL);
|
||||
|
||||
&load_selected_language($hdf);
|
||||
|
||||
&get_available_languages($hdf);
|
||||
|
||||
return $hdf;
|
||||
}
|
||||
|
||||
|
||||
sub load_selected_language {
|
||||
my $data = shift;
|
||||
my $config_language;
|
||||
|
||||
# load $DEFAULT_LANGUAGE - this is necessary, if a translation is incomplete
|
||||
$data->readFile("$LANGUAGE_DIR/$DEFAULT_LANGUAGE" . ".hdf");
|
||||
|
||||
# load configured language, if it is valid
|
||||
$config_language = &get_cbox_config("language");
|
||||
$config_language = $DEFAULT_LANGUAGE unless (&validate_language("$config_language"));
|
||||
|
||||
# check for preferred browser language, if the box was not initialized yet
|
||||
if ( ! &check_config())
|
||||
{
|
||||
my $prefLang = &get_browser_language();
|
||||
# take it, if a supported browser language was found
|
||||
$config_language = $prefLang unless ($prefLang eq '');
|
||||
}
|
||||
|
||||
######### temporary language setting? ############
|
||||
# the default language can be overriden by the language links in the
|
||||
# upper right of the page
|
||||
if ($query->param('weblang')) {
|
||||
my $weblang = $query->param('weblang');
|
||||
if (&validate_language($weblang)) {
|
||||
# load the data
|
||||
$config_language = "$weblang";
|
||||
# add the setting to every link
|
||||
# how it should be done now ...
|
||||
$data->setValue('Settings.LinkAttrs.weblang', "$weblang");
|
||||
# old way of doing this ... (TODO: to be removed)
|
||||
$data->setValue('Data.PostData.weblang', "$weblang");
|
||||
} else {
|
||||
# no valid language was selected - so you may ignore it
|
||||
$data->setValue('Data.Warning', 'InvalidLanguage');
|
||||
}
|
||||
}
|
||||
# import the configured resp. the temporarily selected language
|
||||
$data->readFile("$LANGUAGE_DIR/$config_language" . ".hdf");
|
||||
|
||||
########## select documentation language ##########
|
||||
if (&validate_doc_language($config_language)) {
|
||||
# selected web interface language
|
||||
$data->setValue('Settings.DocLang', "$config_language");
|
||||
} elsif (&validate_doc_language($DEFAULT_LANGUAGE)) {
|
||||
# configured CryptoBox language
|
||||
$data->setValue('Settings.DocLang', "$DEFAULT_LANGUAGE");
|
||||
} else {
|
||||
# default hardcoded language (english)
|
||||
$data->setValue('Settings.DocLang', "en");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# import the names of all available languages
|
||||
sub get_available_languages {
|
||||
my $data = shift;
|
||||
my ($file, @files, $hdf, $lang_name);
|
||||
|
||||
opendir(DIR, $LANGUAGE_DIR) or &fatal_error ("Language directory ($LANGUAGE_DIR) not accessible!");
|
||||
@files = sort grep { /.*\.hdf$/ } readdir(DIR);
|
||||
close(DIR);
|
||||
|
||||
foreach $file (@files) {
|
||||
$hdf = ClearSilver::HDF->new();
|
||||
$hdf->readFile("$LANGUAGE_DIR/$file");
|
||||
substr($file, -4) = "";
|
||||
$lang_name = $hdf->getValue("Lang.Name", "$file");
|
||||
$data->setValue("Data.Languages." . "$file", "$lang_name");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# look for preferred browser language setting
|
||||
# this code was adapted from Per Cederberg - http://www.percederberg.net/home/perl/select.perl
|
||||
# it returns an empty string, if no supported language was found
|
||||
sub get_browser_language {
|
||||
my ($str, @langs, @res);
|
||||
|
||||
# Use language preference settings
|
||||
if ($ENV{'HTTP_ACCEPT_LANGUAGE'} ne '')
|
||||
{
|
||||
@langs = split(/,/, $ENV{'HTTP_ACCEPT_LANGUAGE'});
|
||||
foreach (@langs)
|
||||
{
|
||||
# get the first part of the language setting
|
||||
($str) = ($_ =~ m/([a-z]+)/);
|
||||
# check, if it supported by the cryptobox
|
||||
$res[$#res+1] = $str if validate_language($str);
|
||||
}
|
||||
}
|
||||
|
||||
# if everything fails - return empty string
|
||||
$res[0] = "" if ($#res lt 0);
|
||||
return $res[0];
|
||||
}
|
||||
|
||||
|
||||
sub log_msg {
|
||||
my $text = shift;
|
||||
open(LOGFILE,">> $LOG_FILE");
|
||||
print LOGFILE "$text";
|
||||
close(LOGFILE);
|
||||
}
|
||||
|
||||
|
||||
sub check_ssl {
|
||||
# check, if we are behind a proxy with ssl (e.g. pound)
|
||||
return (0==0) if ($ENV{'HTTP_FRONT_END_HTTPS'} =~ m/^on$/i);
|
||||
# environment variable set (e.g. via apache directive "SetEnv HTTPS On")
|
||||
return (0==0) if ($ENV{'HTTPS'} =~ m/^on$/i);
|
||||
# port 80 -> not encrypted
|
||||
return (0==1) if ($ENV{'SERVER_PORT'} == 80);
|
||||
# other ports -> maybe ok - we accept it
|
||||
return (0==0);
|
||||
}
|
||||
|
||||
|
||||
# check, if the given device is mounted/used somehow
|
||||
# Paramter: device
|
||||
sub check_mounted {
|
||||
my ($dev) = @_;
|
||||
return (system($CB_SCRIPT,"is_mounted",$dev) == 0);
|
||||
}
|
||||
|
||||
|
||||
sub check_config {
|
||||
return (system($CB_SCRIPT,"check_config") == 0);
|
||||
}
|
||||
|
||||
|
||||
sub exec_cb_script {
|
||||
my (@params) = @_;
|
||||
my ($pid, @result);
|
||||
&fatal_error("unable to fork process") unless defined($pid = open(PROG_OUT, "-|"));
|
||||
if (!$pid) {
|
||||
# child
|
||||
exec($CB_SCRIPT, @params) or &fatal_error("failed to execute $CB_SCRIPT!");
|
||||
exit 0;
|
||||
} else {
|
||||
# parent
|
||||
# only read lines containing at least one non-whitespace character
|
||||
@result = grep /\S/, <PROG_OUT>;
|
||||
foreach (@result) { chomp; }
|
||||
unless (close PROG_OUT) {
|
||||
&debug_msg(DEBUG_WARN, "error while running $CB_SCRIPT (params:" . join(" ",@params) . "): $?");
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
if (wantarray) {
|
||||
return @result;
|
||||
} elsif (@result > 0) {
|
||||
return join('',@result);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub check_init_running {
|
||||
# TODO: improve this
|
||||
return (0==1);
|
||||
}
|
||||
|
||||
|
||||
# Parameter: device
|
||||
sub check_device_plaintext {
|
||||
return (system("$CB_SCRIPT","is_plain",$1) == 0);
|
||||
}
|
||||
|
||||
|
||||
# Parameter: device
|
||||
sub check_device_encryption {
|
||||
return (system("$CB_SCRIPT","is_encrypted",$1) == 0);
|
||||
}
|
||||
|
||||
|
||||
sub is_harddisk_available {
|
||||
my @all_disks = &exec_cb_script("get_available_disks");
|
||||
return @all_disks > 0;
|
||||
}
|
||||
|
||||
|
||||
sub get_available_disks {
|
||||
my @all_disks = &exec_cb_script("get_available_disks");
|
||||
my ($disk, @return_disks);
|
||||
foreach $disk (@all_disks) {
|
||||
$disk =~ m#^([/\._\-\w]*)$#;
|
||||
push @return_disks, $1 if ($1);
|
||||
}
|
||||
return @return_disks;
|
||||
}
|
||||
|
||||
|
||||
sub get_disk_name {
|
||||
my ($dev) = @_;
|
||||
my $disk_name = &exec_cb_script("get_device_name", $dev);
|
||||
return $disk_name;
|
||||
}
|
||||
|
||||
|
||||
# return the value of a configuration setting (timeout, language, ip, ...)
|
||||
# Parameter: setting_name
|
||||
sub get_cbox_config {
|
||||
my ($setting) = @_;
|
||||
# tell the exec function, that we want a scalar instead of an array
|
||||
my $scalar = &exec_cb_script("get_config",$setting);
|
||||
return $scalar;
|
||||
}
|
||||
|
||||
|
||||
sub render {
|
||||
my $pagefile = "$HTML_TEMPLATE_DIR/main.cs";
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
||||
my $cs = ClearSilver::CS->new($pagedata);
|
||||
$cs->parseFile($pagefile);
|
||||
|
||||
print $cs->render();
|
||||
}
|
||||
|
||||
|
||||
# mount an encrypted volume
|
||||
# Parameter: device password
|
||||
sub mount_vol {
|
||||
my ($device, $pw) = @_;
|
||||
|
||||
if (&check_mounted($device)) {
|
||||
$pagedata->setValue('Data.Warning', 'IsMounted');
|
||||
} else {
|
||||
if ($pw eq '') {
|
||||
&exec_cb_script("crypto-up", $device);
|
||||
} else {
|
||||
open(PW_INPUT, "| $CB_SCRIPT crypto-up $device");
|
||||
print PW_INPUT $pw;
|
||||
close(PW_INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# unmount a volume
|
||||
# Parameter: device
|
||||
sub umount_vol {
|
||||
my ($device) = @_;
|
||||
if (&check_mounted($device)) {
|
||||
system($CB_SCRIPT, "crypto-down",$device);
|
||||
} else {
|
||||
$pagedata->setValue('Data.Warning', 'NotMounted');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Parameter: device passphrase
|
||||
# ignore passphrase (or leave it empty) to create a plaintext volume
|
||||
sub volume_init {
|
||||
my ($device, $crypto_pw) = @_;
|
||||
my $result;
|
||||
|
||||
# only for encrypted volumes:
|
||||
# write passphrase to a file - necessary as perl in secured mode does not allow
|
||||
# the 'open(FH, "|/bin/prog ....")' call because of possible shell expansion - stupid 'open' :(
|
||||
if ($crypto_pw) {
|
||||
my ($fh, $temp_file);
|
||||
# generate a temporary filename (as suggested by the Perl Cookbook)
|
||||
do { $temp_file = POSIX::tmpnam() }
|
||||
# TODO: reduce the file mask to the minimum - maybe 0600 would be a good choice
|
||||
until $fh = IO::File->new($temp_file, O_RDWR|O_CREAT|O_EXCL);
|
||||
close $fh;
|
||||
unless (open(TMP, ">$temp_file")) {
|
||||
&debug_msg(DEBUG_ERROR, "could not open a temporary file");
|
||||
return (1==0);
|
||||
}
|
||||
print TMP $crypto_pw;
|
||||
close TMP;
|
||||
$result = &exec_cb_script("device_init", $device, $temp_file);
|
||||
unlink ($temp_file) if (-e $temp_file);
|
||||
} else {
|
||||
$result = &exec_cb_script("device_init", $device);
|
||||
}
|
||||
# just to be sure, that the file does not get left behind
|
||||
# usually the script should overwrite and remove it
|
||||
return defined($result);
|
||||
}
|
||||
|
||||
|
||||
sub box_purge {
|
||||
&exec_cb_script("box-purge");
|
||||
}
|
||||
|
||||
|
||||
sub system_poweroff {
|
||||
&exec_cb_script("poweroff");
|
||||
}
|
||||
|
||||
|
||||
sub system_reboot {
|
||||
&exec_cb_script("reboot");
|
||||
}
|
||||
|
||||
|
||||
sub validate_ip {
|
||||
my $ip = shift;
|
||||
my @octets = split /\./, $ip;
|
||||
return 0 if ($#octets == 4);
|
||||
# check for values and non-digits
|
||||
return 0 if (($octets[0] <= 0) || ($octets[0] >= 255) || ($octets[0] =~ /\D/));
|
||||
return 0 if (($octets[1] < 0) || ($octets[1] >= 255) || ($octets[1] =~ /\D/));
|
||||
return 0 if (($octets[2] < 0) || ($octets[2] >= 255) || ($octets[2] =~ /\D/));
|
||||
return 0 if (($octets[3] <= 0) || ($octets[3] >= 255) || ($octets[3] =~ /\D/));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub validate_timeout {
|
||||
my $timeout = shift;
|
||||
return 0 if ($timeout =~ /\D/);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
# check for a valid interface language
|
||||
sub validate_language {
|
||||
my $language = shift;
|
||||
# check for non-alphanumeric character
|
||||
return 0 if ($language =~ /\W/);
|
||||
return 0 if ($language eq "");
|
||||
return 0 if ( ! -e "$LANGUAGE_DIR/$language" . '.hdf');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
# check for a valid documentation language
|
||||
sub validate_doc_language {
|
||||
my $language = shift;
|
||||
# check for non-alphanumeric character
|
||||
return 0 if ($language =~ /\W/);
|
||||
return 0 if ($language eq "");
|
||||
return 0 if ( ! -e "$DOC_DIR/$language");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
################### main #########################
|
||||
|
||||
|
||||
$pagedata = load_hdf();
|
||||
my $current_admin_pw;
|
||||
|
||||
my $action = $query->param('action');
|
||||
$action =~ m#^([\w\._\-]*)$#;
|
||||
$action = ($1)? $1 : '';
|
||||
|
||||
my $device = $query->param('device');
|
||||
$device =~ m#^([/_\-\w\.]*)$#;
|
||||
$device = ($1)? $1 : '';
|
||||
|
||||
# BEWARE: there are two kinds of actions:
|
||||
# * some require a harddisk
|
||||
# * some do not require a harddisk
|
||||
# take care, that you put a new action into the appropriate block below
|
||||
|
||||
# first: check for ssl!
|
||||
if ( ! &check_ssl()) {
|
||||
$pagedata->setValue('Data.Error', 'NoSSL');
|
||||
# remove port number from HTTP_HOST
|
||||
my $hostname = $ENV{'HTTP_HOST'};
|
||||
$hostname =~ s/:[0-9]*//;
|
||||
$pagedata->setValue('Data.Redirect.URL', "https://" . $hostname . $ENV{'SCRIPT_NAME'});
|
||||
$pagedata->setValue('Data.Redirect.Delay', "3");
|
||||
} elsif ($query->param('action')) {
|
||||
#--------------------------------------------------------------#
|
||||
# here you may define all cases that do not require a harddisk #
|
||||
# put all other cases below the harddisk check #
|
||||
#--------------------------------------------------------------#
|
||||
#################### show_log #######################
|
||||
if ($action eq 'show_log') {
|
||||
$pagedata->setValue('Data.Action', 'show_log');
|
||||
##################### doc ############################
|
||||
} elsif ($action eq 'doc') {
|
||||
if ($query->param('page')) {
|
||||
$pagedata->setValue('Data.Doc.Page', $query->param('page'));
|
||||
$pagedata->setValue('Data.Action', 'show_doc');
|
||||
} else {
|
||||
$pagedata->setValue('Data.Doc.Page', 'CryptoBoxUser');
|
||||
$pagedata->setValue('Data.Action', 'show_doc');
|
||||
}
|
||||
##################### poweroff ######################
|
||||
} elsif ($action eq 'system_ask') {
|
||||
$pagedata->setValue('Data.Action', 'form_system');
|
||||
##################### reboot ########################
|
||||
} elsif ($action eq 'shutdown_do') {
|
||||
if ($query->param('type') eq 'reboot') {
|
||||
&system_reboot();
|
||||
$pagedata->setValue('Data.Success', 'ReBoot');
|
||||
$pagedata->setValue('Data.Redirect.Action', 'show_status');
|
||||
$pagedata->setValue('Data.Redirect.Delay', "180");
|
||||
} else {
|
||||
&system_poweroff();
|
||||
$pagedata->setValue('Data.Success', 'PowerOff');
|
||||
}
|
||||
$pagedata->setValue('Data.Action', 'empty');
|
||||
##################### check for a harddisk ##########################
|
||||
# catch this error, to prevent all following actions from execution #
|
||||
#####################################################################
|
||||
} elsif ( ! &is_harddisk_available()) {
|
||||
$pagedata->setValue('Data.Error', 'NoHardDisk');
|
||||
#-------------------------------------------------------#
|
||||
# here you may define all cases that require a harddisk #
|
||||
#-------------------------------------------------------#
|
||||
################ umount_do #######################
|
||||
} elsif ($action eq 'umount_do') {
|
||||
if ($device eq '') {
|
||||
&debug_msg(DEBUG_INFO, "invalid device: " . $query->param('device'));
|
||||
$pagedata->setValue('Data.Warning', 'InvalidDevice');
|
||||
$pagedata->setValue('Data.Action', 'emptu');
|
||||
} elsif ( ! &check_config()) {
|
||||
$pagedata->setValue('Data.Warning', 'NotInitialized');
|
||||
$pagedata->setValue('Data.Action', 'form_init');
|
||||
} elsif (&check_init_running()) {
|
||||
$pagedata->setValue('Data.Warning', 'InitNotFinished');
|
||||
$pagedata->setValue('Data.Action', 'empty');
|
||||
$pagedata->setValue('Data.Redirect.Action', 'form_config');
|
||||
$pagedata->setValue('Data.Redirect.Delay', "30");
|
||||
} elsif ( ! &check_mounted($device)) {
|
||||
$pagedata->setValue('Data.Warning', 'NotMounted');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
} else {
|
||||
# unmounten
|
||||
&umount_vol($device);
|
||||
if (&check_mounted($device)) {
|
||||
$pagedata->setValue('Data.Warning', 'UmountFailed');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
} else {
|
||||
#$pagedata->setValue('Data.Success', 'UmountDone');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
}
|
||||
}
|
||||
################ mount_do ########################
|
||||
} elsif ($action eq 'mount_do') {
|
||||
my $is_encrypted = &check_device_encryption($device) if ($device ne '');
|
||||
if ($device eq '') {
|
||||
&debug_msg(DEBUG_INFO, "invalid device: " . $query->param('device'));
|
||||
$pagedata->setValue('Data.Warning', 'InvalidDevice');
|
||||
$pagedata->setValue('Data.Action', 'empty');
|
||||
} elsif ( ! &check_config()) {
|
||||
$pagedata->setValue('Data.Warning', 'NotInitialized');
|
||||
$pagedata->setValue('Data.Action', 'form_init');
|
||||
} elsif (&check_init_running()) {
|
||||
$pagedata->setValue('Data.Warning', 'InitNotFinished');
|
||||
$pagedata->setValue('Data.Action', 'empty');
|
||||
$pagedata->setValue('Data.Redirect.Action', 'form_config');
|
||||
$pagedata->setValue('Data.Redirect.Delay', "30");
|
||||
} elsif (&check_mounted($device)) {
|
||||
$pagedata->setValue('Data.Warning', 'IsMounted');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
} elsif ($is_encrypted && ($query->param('crypto_password') eq '')) {
|
||||
# leeres Passwort
|
||||
$pagedata->setValue('Data.Warning', 'EmptyCryptoPassword');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
} else {
|
||||
# mounten
|
||||
if ($is_encrypted) {
|
||||
&mount_vol($device, $query->param('crypto_password'));
|
||||
} else {
|
||||
&mount_vol($device);
|
||||
}
|
||||
if (!&check_mounted($device)) {
|
||||
$pagedata->setValue('Data.Warning', 'MountFailed');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
} else {
|
||||
#$pagedata->setValue('Data.Success', 'MountDone');
|
||||
$pagedata->setValue('Data.Action', 'show_volume');
|
||||
}
|
||||
}
|
||||
################## mount_ask #######################
|
||||
} elsif ($action eq 'mount_ask') {
|
||||
if ( ! &check_config()) {
|
||||
$pagedata->setValue('Data.Warning', 'NotInitialized');
|
||||
$pagedata->setValue('Data.Action', 'form_init');
|
||||
} elsif (&check_init_running()) {
|
||||
$pagedata->setValue('Data.Warning', 'InitNotFinished');
|
||||
$pagedata->setValue('Data.Action', 'empty');
|
||||
$pagedata->setValue('Data.Redirect.Action', 'form_config');
|
||||
$pagedata->setValue('Data.Redirect.Delay', "30");
|
||||
} else {
|
||||
$pagedata->setValue('Data.Action', 'form_mount');
|
||||
}
|
||||
################# umount_ask ########################
|
||||
} elsif ($action eq 'umount_ask') {
|
||||
if ( ! &check_config()) {
|
||||
$pagedata->setValue('Data.Warning', 'NotInitialized');
|
||||
$pagedata->setValue('Data.Action', 'form_init');
|
||||
} else {
|
||||
$pagedata->setValue('Data.Action', 'form_umount');
|
||||
}
|
||||
################## init_ask #########################
|
||||
} elsif ($action eq 'init_ask') {
|
||||
if (&check_init_running()) {
|
||||