Ver código fonte

whonix: Added protected-files file used to prevent scripts from modifying files that need to be protected

        A file is created in /var/lib/qubes/protected-files.  Scripts can grep this file before modifying
        known files to be protected and skip any modifications if the file path is within protected-files.

        Usage Example:
            if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then

        Also cleaned up maintainer scripts removing unneeded systemd status functions and streamlined
        the enable/disable systemd unit files functions
Jason Mehring 9 anos atrás
pai
commit
56b0685aaa
5 arquivos alterados com 134 adições e 128 exclusões
  1. 54 76
      debian/qubes-core-agent.postinst
  2. 9 4
      network/setup-ip
  3. 17 10
      rpm_spec/core-vm.spec
  4. 29 21
      vm-init.d/qubes-core
  5. 25 17
      vm-systemd/qubes-sysinit.sh

+ 54 - 76
debian/qubes-core-agent.postinst

@@ -105,80 +105,47 @@ showIn() {
     fi
 }
 
-setArrayAsGlobal() {
-    local array="$1"
-    local export_as="$2"
-    local code=$(declare -p "$array")
-    local replaced="${code/$array/$export_as}"
-    eval ${replaced/declare -/declare -g}
-}
-
-systemdInfo() {
+changeSystemdStatus() {
     unit=${1}
-    return_global_var=${2}
-
-    declare -A INFO=()
-    while read line; do
-        INFO[${line%%=*}]="${line##*=}"
-    done < <(systemctl show ${unit} 2> /dev/null)
-
-    setArrayAsGlobal INFO $return_global_var
-    return ${#INFO[@]}
-}
-
-displayFailedStatus() {
-    action=${1}
-    unit=${2}
-
-    # Only display if there are results.  In chroot environmnet there will be 
-    # no results to 'systemctl show' command
-    systemdInfo ${unit} info || {
-        echo
-        echo "==================================================="
-        echo "FAILED: systemd ${action} ${unit}"
-        echo "==================================================="
-        echo "    LoadState = ${info[LoadState]}"
-        echo "    LoadError = ${info[LoadError]}"
-        echo "  ActiveState = ${info[ActiveState]}"
-        echo "     SubState = ${info[SubState]}"
-        echo "UnitFileState = ${info[UnitFileState]}"
-        echo
-    }
-}
-
-# Disable systemd units
-disableSystemdUnits() {
-    for unit in $*; do
-        echo "Disabling ${unit}..."
-        systemctl is-active ${unit} > /dev/null 2>&1 && {
-            systemctl stop ${unit} > /dev/null 2>&1 || displayFailedStatus stop ${unit}
-        }
-        if [ -f /lib/systemd/system/${unit} ]; then
-            if fgrep -q '[Install]' /lib/systemd/system/${unit}; then
-                systemctl disable ${unit} > /dev/null 2>&1 || displayFailedStatus disable ${unit}
+    disable=${2-0}
+    
+    # Check if unit file is currently active (running)
+    systemctl is-active ${unit} > /dev/null 2>&1 && active=true || unset active
+
+    case ${disable} in
+        0)
+            systemctl --quiet enable ${unit} > /dev/null 2>&1 || true
+            ;;
+        1)  
+            if [ $active ]; then
+                systemctl --quiet stop ${unit} > /dev/null 2>&1 || true
+            fi  
+
+            if [ -f /lib/systemd/system/${unit} ]; then
+                if fgrep -q '[Install]' /lib/systemd/system/${unit}; then
+                    systemctl --quiet disable ${unit} > /dev/null 2>&1 || true
+                else
+                    # Forcibly disable
+                    ln -sf /dev/null /etc/systemd/system/${unit}
+                fi
             else
-                echo "Masking service: ${unit}"
-                systemctl mask ${unit}
+                systemctl --quiet disable ${unit} > /dev/null 2>&1 || true
             fi
-        else
-                systemctl disable ${unit} > /dev/null 2>&1 || displayFailedStatus disable ${unit}
-        fi
-    done
+            ;;
+    esac
 }
 
 # Enable systemd units
 enableSystemdUnits() {
     for unit in $*; do
-        systemctl is-enabled ${unit} > /dev/null 2>&1 && {
-            echo "It appears ${unit} is already enabled!"
-            #displayFailedStatus is-enabled ${unit}
-        } || {
-            echo "Enabling: ${unit}..."
-            systemctl enable ${unit} > /dev/null 2>&1 || {
-                echo "Could not enable: ${unit}"
-                displayFailedStatus enable ${unit}
-            }
-        }
+        changeSystemdStatus ${unit} 0 || true
+    done
+}
+
+# Disable systemd units
+disableSystemdUnits() {
+    for unit in $*; do
+        changeSystemdStatus ${unit} 1 || true
     done
 }
 
@@ -204,6 +171,9 @@ case "${1}" in
             dpkg-divert --divert /etc/init/${init}.conf.qubes-disabled --package qubes-core-agent --rename --add /etc/init/${init}.conf
         done
 
+        # Disable sysv init network-manager
+        disableSystemdUnits network-manager
+
         # Create NetworkManager configuration if we do not have it
         if ! [ -e /etc/NetworkManager/NetworkManager.conf ]; then
             echo '[main]' > /etc/NetworkManager/NetworkManager.conf
@@ -217,19 +187,27 @@ case "${1}" in
             rm -f /lib/firmware/updates
         fi
 
+        # Location of files which contains list of protected files
+        PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
+
         # ensure that hostname resolves to 127.0.1.1 resp. ::1 and that /etc/hosts is
         # in the form expected by qubes-sysinit.sh
-        for ip in '127\.0\.1\.1' '::1'; do
-            if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
-                sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
-                sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts
-            else
-                echo "${ip//\\/} `hostname`" >> /etc/hosts
-            fi
-        done
+        if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+            for ip in '127\.0\.1\.1' '::1'; do
+                if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
+                    sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
+                    sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts || true
+                else
+                    echo "${ip//\\/} `hostname`" >> /etc/hosts || true
+                fi
+            done
+        fi
+
         # remove hostname from 127.0.0.1 line (in debian the hostname is by default
         # resolved to 127.0.1.1)
-        sed -i "/^127\.0\.0\.1\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
+        if ! grep -q "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+            sed -i "/^127\.0\.0\.1\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
+        fi
 
         chown user:user /home_volatile/user
 
@@ -286,7 +264,7 @@ case "${1}" in
             rngd smartd.service \
             upower.service \
             irqbalance.service \
-            colord.service
+            colord.service 
 
         rm -f /etc/systemd/system/getty.target.wants/getty@tty*.service
 

+ 9 - 4
network/setup-ip

@@ -6,6 +6,9 @@
 disablegw=`qubesdb-read /qubes-service/disable-default-route 2> /dev/null`
 disabledns=`qubesdb-read /qubes-service/disable-dns-server 2> /dev/null`
 
+# Location of files which contains list of protected files
+PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
+
 ip=`/usr/bin/qubesdb-read /qubes-ip 2> /dev/null`
 if [ x$ip != x ]; then
     netmask=`/usr/bin/qubesdb-read /qubes-netmask`
@@ -19,10 +22,12 @@ if [ x$ip != x ]; then
     fi
     /sbin/ethtool -K $INTERFACE sg off
     /sbin/ethtool -K $INTERFACE tx off
-    echo > /etc/resolv.conf
-    if [ "x$disabledns" != "x1" ]; then
-        echo "nameserver $gateway" > /etc/resolv.conf
-        echo "nameserver $secondary_dns" >> /etc/resolv.conf
+    if ! grep -q "^/etc/resolv[.]conf$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+   	echo > /etc/resolv.conf
+        if [ "x$disabledns" != "x1" ]; then
+            echo "nameserver $gateway" > /etc/resolv.conf
+            echo "nameserver $secondary_dns" >> /etc/resolv.conf
+        fi
     fi
     if [ -f /var/run/qubes-service/network-manager ]; then
         nm_config=/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE

+ 17 - 10
rpm_spec/core-vm.spec

@@ -239,24 +239,31 @@ fi
 # Revert 'Prevent unnecessary updates in VMs':
 sed -i -e '/^exclude = kernel/d' /etc/yum.conf
 
+# Location of files which contains list of protected files
+PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
+
 # qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content
-if ! grep -q localhost /etc/hosts; then
-  cat <<EOF > /etc/hosts
+if ! grep -q "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+    if ! grep -q localhost /etc/hosts; then
+      cat <<EOF > /etc/hosts
 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 `hostname`
 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
 EOF
+    fi
 fi
 
 # ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is
 # in the form expected by qubes-sysinit.sh
-for ip in '127\.0\.0\.1' '::1'; do
-    if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
-        sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
-        sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts
-    else
-        echo "${ip} `hostname`" >> /etc/hosts
-    fi
-done
+if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+    for ip in '127\.0\.0\.1' '::1'; do
+        if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
+            sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
+            sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts
+        else
+            echo "${ip} `hostname`" >> /etc/hosts
+        fi
+    done
+fi
 
 # Copy ip(|6)tables into place if they do not already exist in filesystem.
 # This prevents conflict with iptables-service

+ 29 - 21
vm-init.d/qubes-core

@@ -16,25 +16,37 @@ start()
 	chmod 666 /proc/u2mfn
 
 	mkdir -p /var/run/xen-hotplug
+	mkdir -p /var/run/qubes
+	chgrp qubes /var/run/qubes
+	chmod 0775 /var/run/qubes
 
-	name=$(/usr/bin/qubesdb-read /name)
-	if ! [ -f /etc/this-is-dvm ] ; then
-		# we don't want to set hostname for DispVM
-		# because it makes some of the pre-created dotfiles invalid (e.g. .kde/cache-<hostname>)
-		# (let's be frank: nobody's gonna use xterm on DispVM)
-		hostname $name
-		sed -i "s/^\(127\.0\.0\.1[\t ].*\) \($name \)\?\(.*\)/\1\2 $name/" /etc/hosts
+	# Location of files which contains list of protected files
+	PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
+
+	# Set the hostname
+	if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+		name=$(/usr/bin/qubesdb-read /name)
+		if ! [ -f /etc/this-is-dvm ] ; then
+			# we don't want to set hostname for DispVM
+			# because it makes some of the pre-created dotfiles invalid (e.g. .kde/cache-<hostname>)
+			# (let's be frank: nobody's gonna use xterm on DispVM)
+			hostname $name
+			sed -i "s/^\(127\.0\.0\.1[\t ].*\) \($name \)\?\(.*\)/\1\2 $name/" /etc/hosts
+		fi
 	fi
 
-	timezone=`/usr/bin/qubesdb-read /qubes-timezone 2> /dev/null`
-	if [ -n "$timezone" ]; then
-		ln -f /usr/share/zoneinfo/$timezone /etc/localtime
-		echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
-		echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
+	# Set the timezone
+	if ! grep -q "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+		timezone=`/usr/bin/qubesdb-read /qubes-timezone 2> /dev/null`
+		if [ -n "$timezone" ]; then
+			ln -f /usr/share/zoneinfo/$timezone /etc/localtime
+			echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
+			echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
+		fi
 	fi
 
 	yum_proxy_setup=$(/usr/bin/qubesdb-read /qubes-service/yum-proxy-setup 2> /dev/null || /usr/bin/qubesdb-read /qubes-service/updates-proxy-setup 2> /dev/null)
-    type=$(/usr/bin/qubesdb-read /qubes-vm-type)
+	type=$(/usr/bin/qubesdb-read /qubes-vm-type)
 	if [ "$yum_proxy_setup" != "0" ] || [ -z "$yum_proxy_setup" -a "$type" == "TemplateVM" ]; then
 		echo proxy=http://10.137.255.254:8082/ > /etc/yum.conf.d/qubes-proxy.conf
 	else
@@ -47,10 +59,6 @@ start()
 	# qubesdb-read fails
 	INTERFACE=eth0 /usr/lib/qubes/setup-ip
 
-	mkdir -p /var/run/qubes
-	chgrp qubes /var/run/qubes
-	chmod 0775 /var/run/qubes
-
 	if [ -e /dev/xvdb ] ; then
 		# check if private.img (xvdb) is empty - all zeros
 		private_size_512=`blockdev --getsz /dev/xvdb`
@@ -64,11 +72,11 @@ start()
 		resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed"
 
         if ! [ -d /rw/home ] ; then
-            echo
-            echo "--> Virgin boot of the VM: Linking /home to /rw/home"
+        	echo
+        	echo "--> Virgin boot of the VM: Linking /home to /rw/home"
 
-            mkdir -p /rw/config
-			cat > /rw/config/rc.local <<EOF
+        	mkdir -p /rw/config
+		cat > /rw/config/rc.local <<EOF
 #!/bin/sh
 
 # This script will be executed at every VM startup, you can place your own

+ 25 - 17
vm-systemd/qubes-sysinit.sh

@@ -10,6 +10,9 @@ DEFAULT_ENABLED="meminfo-writer"
 QDB_READ=qubesdb-read
 QDB_LS=qubesdb-multiread
 
+# Location of files which contains list of protected files
+PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
+
 read_service() {
     $QDB_READ /qubes-service/$1 2> /dev/null
 }
@@ -67,26 +70,31 @@ for srv in `$QDB_LS /qubes-service/ 2>/dev/null |grep ' = 0'|cut -f 1 -d ' '`; d
 done
 
 # Set the hostname
-name=`$QDB_READ /name`
-if [ -n "$name" ]; then
-    hostname $name
-    if [ -e /etc/debian_version ]; then
-        ipv4_localhost_re="127\.0\.1\.1"
-    else
-        ipv4_localhost_re="127\.0\.0\.1"
+if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+    name=`$QDB_READ /name`
+    if [ -n "$name" ]; then
+        hostname $name
+        if [ -e /etc/debian_version ]; then
+            ipv4_localhost_re="127\.0\.1\.1"
+        else
+            ipv4_localhost_re="127\.0\.0\.1"
+        fi
+        sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
+        sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
     fi
-    sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
-    sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
 fi
 
-timezone=`$QDB_READ /qubes-timezone 2> /dev/null`
-if [ -n "$timezone" ]; then
-    cp -p /usr/share/zoneinfo/$timezone /etc/localtime
-    if [ -e /etc/debian_version ]; then
-        echo "$timezone" > /etc/timezone
-    else
-        echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
-        echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
+# Set the timezone
+if ! grep -q "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
+    timezone=`$QDB_READ /qubes-timezone 2> /dev/null`
+    if [ -n "$timezone" ]; then
+        cp -p /usr/share/zoneinfo/$timezone /etc/localtime
+        if [ -e /etc/debian_version ]; then
+            echo "$timezone" > /etc/timezone
+        else
+            echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
+            echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
+        fi
     fi
 fi