diff --git a/DEBIAN/postinst b/DEBIAN/postinst index bb6ed6e..904e670 100755 --- a/DEBIAN/postinst +++ b/DEBIAN/postinst @@ -1,5 +1,23 @@ #!/bin/sh +# read the default setting file, if it exists +[ -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 +if [ -e "$CONF_FILE" ] + then . "$CONF_FILE" + # create mount and config directories with appropriate permissions + [ ! -e "$MNT_PARENT" ] && mkdir -p "$MNT_PARENT" && \ + chown "$WEB_USER" "$MNT_PARENT" && chmod 700 "$MNT_PARENT" + [ ! -e "$CONFIG_DIR" ] && mkdir -p "$CONFIG_DIR" && \ + chown "$WEB_USER" "$CONFIG_DIR" && chmod 700 "$CONFIG_DIR" + [ ! -e "$LOG_FILE" ] && touch "$LOG_FILE" && chown "$WEB_USER" "$LOG_FILE" + fi + + # add the cryptobox startup script to /etc/rc?.d update-rc.d cryptobox defaults 98 diff --git a/DEBIAN/postrm b/DEBIAN/postrm index 2d8c2b2..f24e5e4 100755 --- a/DEBIAN/postrm +++ b/DEBIAN/postrm @@ -6,6 +6,12 @@ if [ "$1" = "purge" ] && grep -q "cryptobox package.*HEADER" /etc/sudoers then echo "Removing entry from /etc/sudoers" sed -i "/cryptobox package.*HEADER/,/cryptobox package.*FOOTER/d" /etc/sudoers + echo "Removing mount and config directories (/var/lib/cryptobox) ..." + rmdir /var/lib/cryptobox/mnt || echo " mount directory not empty - skipped" >&2 + mountpoint -q /var/lib/cryptobox/config || rm -rf /var/lib/cryptobox/config || \ + echo " failed to remove config directory - skipped" >&2 + rmdir /var/lib/cryptobox || \ + echo " the cryptobox directory (/var/lib/cryptobox) has not been removed" >&2 fi # return without error diff --git a/cbox-tree.d/etc/cryptobox/cryptobox.conf b/cbox-tree.d/etc/cryptobox/cryptobox.conf index 7b43915..75fd7f8 100644 --- a/cbox-tree.d/etc/cryptobox/cryptobox.conf +++ b/cbox-tree.d/etc/cryptobox/cryptobox.conf @@ -29,7 +29,7 @@ DEV_FEATURES_SCRIPT=/usr/lib/cryptobox/devel-features.sh FIREWALL_SCRIPT=/usr/lib/cryptobox/firewall.sh MAKE_CERT_SCRIPT=/usr/lib/cryptobox/make_stunnel_cert.sh LOG_FILE=/var/log/cryptobox.log -CERT_FILE=/mnt/cb-etc/stunnel.pem +CERT_FILE=/var/lib/cryptobox/config/stunnel.pem OPENSSL_CONF_FILE=/etc/cryptobox/ssl-cert.conf IDLE_COUNTER_FILE=/tmp/cbox-idle-counter CONFIG_MARKER=cryptobox.marker @@ -37,7 +37,7 @@ CONFIG_MARKER=cryptobox.marker # crypto settings # there is no default hash, as this is ignored by luks DEFAULT_CIPHER=aes-cbc-essiv:sha256 -CRYPTMAPPER_DIR=/dev/mapper +DEV_MAPPER_DIR=/dev/mapper # some programs SFDISK=/sbin/sfdisk diff --git a/cbox-tree.d/etc/init.d/cryptobox b/cbox-tree.d/etc/init.d/cryptobox index 48283b3..a5d5065 100755 --- a/cbox-tree.d/etc/init.d/cryptobox +++ b/cbox-tree.d/etc/init.d/cryptobox @@ -47,8 +47,7 @@ case "$1" in # otherwise give a warning and start the devel features if [ ! -e "$DEV_FEATURES_SCRIPT" ]; then echo - echo "Hints for usage:" - echo " * for some reasons you can not login here :)" + echo "How to use the CryptoBox:" echo " * point a webbrowser from another computer to 'http://$(/usr/lib/cryptobox/cbox-manage.sh get_current_ip)'" echo " * configure your CryptoBox via a webbrowser" echo diff --git a/cbox-tree.d/usr/lib/cgi-bin/cryptobox.pl b/cbox-tree.d/usr/lib/cgi-bin/cryptobox.pl index 68c6aca..44c6b8d 100755 --- a/cbox-tree.d/usr/lib/cgi-bin/cryptobox.pl +++ b/cbox-tree.d/usr/lib/cgi-bin/cryptobox.pl @@ -38,7 +38,7 @@ $IS_DEVEL = ( -e $config->{DEV_FEATURES_SCRIPT}); $STYLESHEET_URL = $config->{STYLESHEET_URL}; # TODO: just a quick-and-dirty hack during migration to multiple containers -my $CRYPTO_DEV = "`$CB_SCRIPT get_config device`2"; +my $CRYPTO_DEV = `$CB_SCRIPT get_available_disks | cut -f 1 -d " " | tr "\n" "2"`; my $query = new CGI; @@ -286,11 +286,11 @@ sub box_init { my ($crypto_pw, $admin_pw) = @_; - system("$CB_SCRIPT", "init"); + system("$CB_SCRIPT", "init") || return 1; + # partitioning, config and initial cryptsetup # TODO: define the name of the crypto container - # TODO: split init and create_crypto - open(PW_INPUT, "|$CB_SCRIPT crypto-create",$CRYPTO_DEV,"default"); + open(PW_INPUT, "|$CB_SCRIPT crypto-create '$CRYPTO_DEV' default"); print PW_INPUT $crypto_pw; close(PW_INPUT); @@ -404,7 +404,7 @@ if ( ! &check_ssl()) { if ($query->param('type') eq 'reboot') { &system_reboot(); $pagedata->setValue('Data.Success', 'ReBoot'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "180"); } else { &system_poweroff(); @@ -441,7 +441,7 @@ if ( ! &check_ssl()) { } else { $pagedata->setValue('Data.Success', 'UmountDone'); $pagedata->setValue('Data.Action', 'empty'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } } @@ -459,7 +459,7 @@ if ( ! &check_ssl()) { } elsif (&check_mounted()) { $pagedata->setValue('Data.Warning', 'IsMounted'); $pagedata->setValue('Data.Action', 'empty'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } elsif ($query->param('crypto_password') eq '') { # leeres Passwort @@ -474,7 +474,7 @@ if ( ! &check_ssl()) { } else { $pagedata->setValue('Data.Success', 'MountDone'); $pagedata->setValue('Data.Action', 'empty'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } } @@ -491,7 +491,7 @@ if ( ! &check_ssl()) { } elsif (&check_mounted()) { $pagedata->setValue('Data.Warning', 'IsMounted'); $pagedata->setValue('Data.Action', 'empty'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } else { $pagedata->setValue('Data.Action', 'form_mount'); @@ -504,7 +504,7 @@ if ( ! &check_ssl()) { } elsif ( ! &check_mounted()) { $pagedata->setValue('Data.Warning', 'NotMounted'); $pagedata->setValue('Data.Action', 'empty'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } else { $pagedata->setValue('Data.Action', 'form_umount'); @@ -606,8 +606,8 @@ if ( ! &check_ssl()) { } else { $pagedata->setValue('Data.Success', 'ConfigSaved'); } - $pagedata->setValue('Data.Action', 'show_status'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Action', 'status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "30"); } } @@ -622,8 +622,8 @@ if ( ! &check_ssl()) { $pagedata->setValue('Data.Redirect.Action', 'form_config'); $pagedata->setValue('Data.Redirect.Delay', "30"); } else { - $pagedata->setValue('Data.Action', 'show_status'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Action', 'status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "60"); } ################### box_purge ####################### @@ -655,8 +655,8 @@ if ( ! &check_ssl()) { $pagedata->setValue('Data.Redirect.Action', 'form_config'); $pagedata->setValue('Data.Redirect.Delay', "60"); } elsif (&check_config()) { - $pagedata->setValue('Data.Action', 'show_status'); - $pagedata->setValue('Data.Redirect.Action', 'show_status'); + $pagedata->setValue('Data.Action', 'status'); + $pagedata->setValue('Data.Redirect.Action', 'status'); $pagedata->setValue('Data.Redirect.Delay', "60"); } else { $pagedata->setValue('Data.Action', 'form_init'); diff --git a/cbox-tree.d/usr/lib/cryptobox/cbox-manage.sh b/cbox-tree.d/usr/lib/cryptobox/cbox-manage.sh index f9276a9..8f7c602 100755 --- a/cbox-tree.d/usr/lib/cryptobox/cbox-manage.sh +++ b/cbox-tree.d/usr/lib/cryptobox/cbox-manage.sh @@ -20,11 +20,16 @@ set -eu +# define reasonable defaults +USE_STUNNEL=0 +EXEC_FIREWALL_RULES=0 +SKIP_NETWORK_CONFIG=1 +CONF_FILE=/etc/cryptobox/cryptobox.conf + + # read the default setting file, if it exists [ -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" @@ -106,7 +111,7 @@ function create_config() { local device=$1 # create the new configuration filesystem if it is not static - if is_config_active + if is_config_active || [ "$USE_SEPERATE_CONFIG_PARTITION" != "1" ] then log_msg "Using static configuration ..." else log_msg "Creating config filesystem ..." sudo "$ROOT_PERM_SCRIPT" create_config "$device" @@ -114,20 +119,21 @@ function create_config() sudo "$ROOT_PERM_SCRIPT" mount_config "$device" sudo "$ROOT_PERM_SCRIPT" remount_config rw fi - # create a marker to recognize a cryptobox partition - date -I >"$CONFIG_DIR/$CONFIG_MARKER" log_msg "Copying configuration defaults ..." cp -a "$CONFIG_DEFAULTS_DIR/." "$CONFIG_DIR" log_msg "Copying temporary certificate file to config filesystem ..." # beware: the temp file should always be there - even after reboot - see "load_config" - cp -p "$CERT_TEMP" "$CERT_FILE" + [ "$USE_STUNNEL" = 1 ] && cp -p "$CERT_TEMP" "$CERT_FILE" log_msg "Setting inital values ..." # beware: config_set_value remounts the config partition read-only config_set_value "ip" "$(get_current_ip)" # create database of readable names config_set_value "names.db" "" + # create a marker to recognize a cryptobox partition + # this should be the last step, to prevent a half-initialized state + config_set_value "$CONFIG_MARKER" "$(date -I)" } @@ -308,7 +314,7 @@ function load_config() sudo "$ROOT_PERM_SCRIPT" mount_config "/dev/$part" # copy certificate to /tmp in case of re-initialization # /tmp should be writable, so tmpfs has to be mounted before (/etc/rcS.d) - cp "$CERT_FILE" "$CERT_TEMP" + [ "$USE_STUNNEL" = 1 ] && cp "$CERT_FILE" "$CERT_TEMP" return fi done @@ -336,7 +342,7 @@ function mount_crypto() is_crypto_mounted "$device" && echo "The crypto filesystem is already active!" && return # passphrase is read from stdin log_msg "Mounting a crypto partition from $device" - sudo "$ROOT_PERM_SCRIPT" mount "$device" + sudo "$ROOT_PERM_SCRIPT" mount "$device" >>"$LOG_FILE" 2>&1 } @@ -351,11 +357,12 @@ function umount_crypto() function box_purge() # removing just the first bytes from the harddisk should be enough +# every harddisk will be overriden! { + # TODO: not ALL harddisks, please! get_available_disks | while read a do log_msg "Purging $a ..." - sudo "$ROOT_PERM_SCRIPT" trash_device "$a" - log_msg " " + sudo "$ROOT_PERM_SCRIPT" trash_device "$a" >>"$LOG_FILE" 2>&1 done } @@ -368,7 +375,7 @@ function init_cryptobox() turn_off_all_crypto is_config_active && umount_config || true log_msg "Partitioning the device ($device) ..." - create_partitions "$device" + sudo "$ROOT_PERM_SCRIPT" partition_disk "$device" "0,1,L \n,,L\n" log_msg "Initializing config partition on ${device}1 ..." # TODO: this should not be hard-coded create_config "${device}1" @@ -394,31 +401,37 @@ ACTION=help case "$ACTION" in config-up ) - if mount_config + if load_config then echo "Cryptobox configuration successfully loaded" else error_msg 0 "Could not find a configuration partition!" fi ;; config-down ) - umount_config || error_msg 4 "Could not unmount configuration partition" + if is_config_active && [ "$USE_SEPERATE_CONFIG_PARTITION" = "1" ] + then umount_config || error_msg 4 "Could not unmount configuration partition" + else true + fi ;; network-up ) - if [ "${SKIP_NETWORK_CONFIG:-1}" != 1 ] + if [ "$SKIP_NETWORK_CONFIG}" != 1 ] then conf_ip=$(config_get_value "ip") log_msg "Configuring $NET_IFACE for $conf_ip ..." echo "Configuring network interface for $NET_IFACE: $conf_ip" "$IFCONFIG" "$NET_IFACE" "$conf_ip" fi - if [ "${EXEC_FIREWALL_RULES:-0}" = 1 ] + if [ "$EXEC_FIREWALL_RULES" = 1 ] then log_msg "Starting the firewall ..." "$FIREWALL_SCRIPT" start fi - if [ "${USE_STUNNEL:-0}" = 1 ] + if [ "$USE_STUNNEL" = 1 ] then # start stunnel if [ -f "$CERT_FILE" ] then USE_CERT=$CERT_FILE else USE_CERT=$CERT_TEMP $MAKE_CERT_SCRIPT "$CERT_TEMP" >>"$LOG_FILE" 2>&1 + # TODO: this could be dangerous - right? + # this is necessary, to allow www-data to copy the certificate + chown "$WEB_USER" "$CERT_TEMP" fi log_msg "Starting stunnel ..." stunnel -p "$USE_CERT" -r localhost:80 -d 443 \ @@ -426,15 +439,15 @@ case "$ACTION" in fi ;; network-down ) - if [ "${EXEC_FIREWALL_RULES:-0}" = 1 ] + if [ "$EXEC_FIREWALL_RULES" = 1 ] then log_msg "Stopping the firewall ..." "$FIREWALL_SCRIPT" stop fi - if [ "${USE_STUNNEL:-0}" = 1 ] + if [ "$USE_STUNNEL" = 1 ] then log_msg "Stopping stunnel ..." killall stunnel fi - if [ "${SKIP_NETWORK_CONFIG:-1}" != 1 ] + if [ "$SKIP_NETWORK_CONFIG" != 1 ] then log_msg "Shutting the network interface down ..." "$IFCONFIG" "$NET_IFACE" down fi @@ -505,7 +518,7 @@ case "$ACTION" in update_ip_address ) # reconfigure the network interface to a new IP address # wait for 5 seconds to finish present http requests - if [ "${SKIP_NETWORK_CONFIG:-1}" != 1 ] + if [ "$SKIP_NETWORK_CONFIG" != 1 ] then echo -n "sleep 5; sudo $ROOT_PERM_SCRIPT update_network" | at now fi ;; @@ -573,3 +586,6 @@ case "$ACTION" in echo ;; esac + +exit 0 + diff --git a/cbox-tree.d/usr/lib/cryptobox/cbox-root-actions.sh b/cbox-tree.d/usr/lib/cryptobox/cbox-root-actions.sh index 9d22eb1..0d33271 100755 --- a/cbox-tree.d/usr/lib/cryptobox/cbox-root-actions.sh +++ b/cbox-tree.d/usr/lib/cryptobox/cbox-root-actions.sh @@ -84,8 +84,11 @@ 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) - echo -e "$2" | "$SFDISK" -n "$1" && \ - echo -e "$2" | "$SFDISK" "$1" + if echo -e "$2" | "$SFDISK" -n "$1" + then echo -e "$2" | "$SFDISK" "$1" || return 1 + else return 2 + fi + true } @@ -165,9 +168,9 @@ case "$ACTION" in error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)" # read the passphrase from stdin key=$(cat -) - # the iter-time is in milliseconds + # the iter-time is in milliseconds - keep it low for fast mounting echo "$key" | \ - "$CRYPTSETUP" --cipher "$DEFAULT_CIPHER" --iter-time 50000 luksFormat "$1" || \ + "$CRYPTSETUP" --cipher "$DEFAULT_CIPHER" --iter-time 2000 luksFormat "$1" || \ error_msg 11 "failed to create the encrypted partition" name=$(get_device_name "$1") echo "$key" | "$CRYPTSETUP" luksOpen "$1" "$name" || \ @@ -185,6 +188,18 @@ case "$ACTION" in error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)" get_device_name "$1" ;; + mount_config ) + # parameter: device + [ $# -ne 1 ] && error_msg 1 "wrong number of parameters" + [ "$USE_SEPERATE_CONFIG_DIR" != "1" ] && \ + error_msg 19 "I am configured to work without a seperate config partition (see $CONF_FILE)" + is_device_allowed "$1" || \ + error_msg 3 "this device ($1) is not listed in SCAN_DEVICES (see $CONF_FILE)" + mountpoint -q "$CONFIG_DIR" && \ + error_msg 0 "the configuration partition is already mounted" + "$MKFS_CONFIG" -q "$1" || \ + error_msg 20 "failed to create config partition filesystem" + ;; mount_config ) # parameter: device [ $# -ne 1 ] && error_msg 1 "wrong number of parameters" diff --git a/cbox-tree.d/var/lib/cryptobox/config/.placeholder b/cbox-tree.d/var/lib/cryptobox/config/.placeholder deleted file mode 100644 index e293edf..0000000 --- a/cbox-tree.d/var/lib/cryptobox/config/.placeholder +++ /dev/null @@ -1 +0,0 @@ -DO NOT REMOVE THIS FILE - it is a placeholder for the debian installer diff --git a/cbox-tree.d/var/lib/cryptobox/mnt/.placeholder b/cbox-tree.d/var/lib/cryptobox/mnt/.placeholder deleted file mode 100644 index e293edf..0000000 --- a/cbox-tree.d/var/lib/cryptobox/mnt/.placeholder +++ /dev/null @@ -1 +0,0 @@ -DO NOT REMOVE THIS FILE - it is a placeholder for the debian installer diff --git a/cbox-tree.d/var/www/cryptobox-misc/cryptobox.css b/cbox-tree.d/var/www/cryptobox-misc/cryptobox.css index c6641ce..e12c610 100644 --- a/cbox-tree.d/var/www/cryptobox-misc/cryptobox.css +++ b/cbox-tree.d/var/www/cryptobox-misc/cryptobox.css @@ -344,6 +344,7 @@ button:hover { margin-left: 10%; margin-right: 10%; font-family: monospace + text-align: left; } /* ---------=-=-=-=- onscreen help -=-=-=-=--------- */