# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 02e104bf03c0016622f6a58283d680e33b515de8
# Parent 0161d68cff37964498c29c24df1e27039b53b0c9
New scripts I missed from previous security patch.
diff -r 0161d68cff37 -r 02e104bf03c0 tools/security/getlabel.sh
--- /dev/null Fri Sep 2 07:59:12 2005
+++ b/tools/security/getlabel.sh Fri Sep 2 08:06:59 2005
@@ -0,0 +1,130 @@
+#!/bin/sh
+# *
+# * getlabel
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# * 'getlabel' tries to find the labels corresponding to the ssidref
+# *
+# * 'getlabel -?' shows the usage of the program
+# *
+# * 'getlabel -sid <ssidref> [<policy name>]' lists the label corresponding
+# * to the given ssidref.
+# *
+# * 'getlabel -dom <domain id> [<policy name>]' lists the label of the
+# * domain with given id
+# *
+#
+
+if [ -z "$runbash" ]; then
+ runbash="1"
+ export runbash
+ exec sh -c "bash $0 $*"
+fi
+
+
+export PATH=$PATH:.
+source labelfuncs.sh
+
+usage ()
+{
+ echo "Usage: $0 -sid <ssidref> [<policy name>] or"
+ echo " $0 -dom <domid> [<policy name>] "
+ echo ""
+ echo "policy name : the name of the policy, i.e. 'chwall'"
+ echo " If the policy name is omitted, the grub.conf"
+ echo " entry of the running system is tried to be read"
+ echo " and the policy name determined from there."
+ echo "ssidref : an ssidref in hex or decimal format, i.e.,
'0x00010002'"
+ echo " or '65538'"
+ echo "domid : id of the domain, i.e., '1'; Use numbers from the
2nd"
+ echo " column shown when invoking 'xm list'"
+ echo ""
+}
+
+
+
+if [ "$1" == "-?" ]; then
+ mode="usage"
+elif [ "$1" == "-dom" ]; then
+ mode="domid"
+ shift
+elif [ "$1" == "-sid" ]; then
+ mode="sid"
+ shift
+elif [ "$1" == "" ]; then
+ usage
+ exit -1
+fi
+
+
+if [ "$mode" == "usage" ]; then
+ usage
+elif [ "$mode" == "domid" ]; then
+ if [ "$2" == "" ]; then
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+ else
+ policy=$2
+ fi
+ findMapFile $policy
+ res=$?
+ if [ "$res" != "0" ]; then
+ getSSIDUsingSecpolTool $1
+ res=$?
+ if [ "$res" != "0" ]; then
+ translateSSIDREF $ssid $mapfile
+ else
+ echo "Could not determine the SSID of the domain."
+ fi
+ else
+ echo "Could not find map file for policy '$policy'."
+ fi
+elif [ "$mode" == "sid" ]; then
+ if [ "$2" == "" ]; then
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+ else
+ policy=$2
+ fi
+ findMapFile $policy
+ res=$?
+ if [ "$res" != "0" ]; then
+ translateSSIDREF $1 $mapfile
+ else
+ echo "Could not find map file for policy '$policy'."
+ fi
+
+else
+ usage
+fi
diff -r 0161d68cff37 -r 02e104bf03c0 tools/security/labelfuncs.sh
--- /dev/null Fri Sep 2 07:59:12 2005
+++ b/tools/security/labelfuncs.sh Fri Sep 2 08:06:59 2005
@@ -0,0 +1,675 @@
+# *
+# * labelfuncs.sh
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# *
+# * A collection of functions to handle polcies, mapfiles,
+# * and ssidrefs.
+#
+
+
+# Find the mapfile given a policy nmame
+# Parameters:
+# 1st : the name of the policy whose map file is to be found, i.e.,
+# chwall
+# Results:
+# The variable mapfile will hold the realtive path to the mapfile
+# for the given policy.
+# In case the mapfile could be found, the functions returns a '1',
+# a '0' otherwise.
+findMapFile ()
+{
+ mapfile="./$1.map"
+ if [ -r "$mapfile" ]; then
+ return 1
+ fi
+
+ mapfile="./policies/$1/$1.map"
+ if [ -r "$mapfile" ]; then
+ return 1
+ fi
+
+ return 0
+}
+
+
+# Determine the name of the primary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+# to the current directory
+# Results
+# The variable primary will hold the name of the primary policy
+getPrimaryPolicy ()
+{
+ mapfile=$1
+ primary=`cat $mapfile | \
+ awk ' \
+ { \
+ if ( $1 == "PRIMARY" ) { \
+ res=$2; \
+ } \
+ } END { \
+ print res; \
+ } '`
+}
+
+
+# Determine the name of the secondary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+# to the current directory
+# Results
+# The variable secondary will hold the name of the secondary policy
+getSecondaryPolicy ()
+{
+ mapfile=$1
+ secondary=`cat $mapfile | \
+ awk ' \
+ { \
+ if ( $1 == "SECONDARY" ) { \
+ res=$2; \
+ } \
+ } END { \
+ print res; \
+ } '`
+}
+
+
+#Return where the grub.conf file is.
+#I only know of one place it can be.
+findGrubConf()
+{
+ grubconf="/boot/grub/grub.conf"
+ if [ -w $grubconf ]; then
+ return 1
+ fi
+ if [ -r $grubconf ]; then
+ return 2
+ fi
+ return 0
+}
+
+
+# This function sets the global variable 'linux'
+# to the name and version of the Linux kernel that was compiled
+# for domain 0.
+# If this variable could not be found, the variable 'linux'
+# will hold a pattern
+# Parameters:
+# 1st: the path to reach the root directory of the XEN build tree
+# where linux-*-xen0 is located at
+# Results:
+# The variable linux holds then name and version of the compiled
+# kernel, i.e., 'vmlinuz-2.6.12-xen0'
+getLinuxVersion ()
+{
+ path=$1
+ linux=""
+ for f in $path/linux-*-xen0 ; do
+ versionfile=$f/include/linux/version.h
+ if [ -r $versionfile ]; then
+ lnx=`cat $versionfile | \
+ grep UTS_RELEASE | \
+ awk '{ \
+ len=length($3); \
+ print substr($3,2,len-2) }'`
+ fi
+ if [ "$lnx" != "" ]; then
+ linux="[./0-9a-zA-z]*$lnx"
+ return;
+ fi
+ done
+
+ #Last resort.
+ linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
+}
+
+
+# Find out with which policy the hypervisor was booted with.
+# Parameters
+# 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
+#
+findPolicyInGrub ()
+{
+ grubconf=$1
+ linux=`uname -r`
+ policy=`cat $grubconf | \
+ awk -vlinux=$linux '{ \
+ if ( $1 == "title" ) { \
+ kernelfound = 0; \
+ policymaycome = 0; \
+ } \
+ else if ( $1 == "kernel" ) { \
+ if ( match($2,"xen.gz$") ) { \
+ pathlen=RSTART; \
+ kernelfound = 1; \
+ } \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ match($2,linux) ) { \
+ policymaycome = 1; \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ policymaycome == 1 && \
+ match($2,"[0-9a-zA-Z_]*.bin$") ) { \
+ policymaycome = 0; \
+ kernelfound = 0; \
+ polname = substr($2,pathlen); \
+ len=length(polname); \
+ polname = substr(polname,0,len-4); \
+ } \
+ } END { \
+ print polname \
+ }'`
+}
+
+
+# Get the SSID of a domain
+# Parameters:
+# 1st : domain ID, i.e. '1'
+# Results
+# If the ssid could be found, the variable 'ssid' will hold
+# the currently used ssid in the hex format, i.e., '0x00010001'.
+# The funtion returns '1' on success, '0' on failure
+getSSIDUsingSecpolTool ()
+{
+ domid=$1
+ export PATH=$PATH:.
+ ssid=`secpol_tool getssid -d $domid -f | \
+ grep -E "SSID:" | \
+ awk '{ print $4 }'`
+
+ if [ "$ssid" != "" ]; then
+ return 1
+ fi
+ return 0
+}
+
+
+# Break the ssid identifier into its high and low values,
+# which are equal to the secondary and primary policy references.
+# Parameters:
+# 1st: ssid to break into high and low value, i.e., '0x00010002'
+# Results:
+# The variable ssidlo_int and ssidhi_int will hold the low and
+# high ssid values as integers.
+getSSIDLOHI ()
+{
+ ssid=$1
+ ssidlo_int=`echo $ssid | awk \
+ '{ \
+ len=length($0); \
+ beg=substr($0,1,2); \
+ if ( beg == "0x" ) { \
+ dig = len - 2; \
+ if (dig <= 0) { \
+ exit; \
+ } \
+ if (dig > 4) { \
+ dig=4; \
+ } \
+ lo=sprintf("0x%s",substr($0,len-dig+1,dig)); \
+ print strtonum(lo);\
+ } else { \
+ lo=strtonum($0); \
+ if (lo < 65536) { \
+ print lo; \
+ } else { \
+ hi=lo; \
+ hi2= (hi / 65536);\
+ hi2_str=sprintf("%d",hi2); \
+ hi2=strtonum(hi2_str);\
+ lo=hi-(hi2*65536); \
+ printf("%d",lo); \
+ } \
+ } \
+ }'`
+ ssidhi_int=`echo $ssid | awk \
+ '{ \
+ len=length($0); \
+ beg=substr($0,1,2); \
+ if ( beg == "0x" ) { \
+ dig = len - 2; \
+ if (dig <= 0 || \
+ dig > 8) { \
+ exit; \
+ } \
+ if (dig < 4) { \
+ print 0; \
+ exit; \
+ } \
+ dig -= 4; \
+ hi=sprintf("0x%s",substr($0,len-4-dig+1,dig)); \
+ print strtonum(hi);\
+ } else { \
+ hi=strtonum($0); \
+ if (hi >= 65536) { \
+ hi = hi / 65536; \
+ printf ("%d",hi);\
+ } else { \
+ printf ("0"); \
+ } \
+ } \
+ }'`
+ if [ "$ssidhi_int" == "" -o \
+ "$ssidlo_int" == "" ]; then
+ return 0;
+ fi
+ return 1
+}
+
+
+#Update the grub configuration file.
+#Search for existing entries and replace the current
+#policy entry with the policy passed to this script
+#
+#Arguments passed to this function
+# 1st : the grub configuration file with full path
+# 2nd : the binary policy file name, i.e. chwall.bin
+# 3rd : the name or pattern of the linux kernel name to match
+# (this determines where the module entry will be made)
+#
+# The algorithm here is based on pattern matching
+# and is working correctly if
+# - under a title a line beginning with 'kernel' is found
+# whose following item ends with "xen.gz"
+# Example: kernel /xen.gz dom0_mem=....
+# - a module line matching the 3rd parameter is found
+#
+updateGrub ()
+{
+ grubconf=$1
+ policyfile=$2
+ linux=$3
+
+ tmpfile="/tmp/new_grub.conf"
+
+ cat $grubconf | \
+ awk -vpolicy=$policyfile \
+ -vlinux=$linux '{ \
+ if ( $1 == "title" ) { \
+ kernelfound = 0; \
+ if ( policymaycome == 1 ){ \
+ printf ("\tmodule %s%s\n", path, policy); \
+ } \
+ policymaycome = 0; \
+ } \
+ else if ( $1 == "kernel" ) { \
+ if ( match($2,"xen.gz$") ) { \
+ path=substr($2,1,RSTART-1); \
+ kernelfound = 1; \
+ } \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ match($2,linux) ) { \
+ policymaycome = 1; \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ policymaycome == 1 && \
+ match($2,"[0-9a-zA-Z]*.bin$") ) { \
+ printf ("\tmodule %s%s\n", path, policy); \
+ policymaycome = 0; \
+ kernelfound = 0; \
+ dontprint = 1; \
+ } \
+ else if ( $1 == "" && \
+ kernelfound == 1 && \
+ policymaycome == 1) { \
+ dontprint = 1; \
+ } \
+ if (dontprint == 0) { \
+ printf ("%s\n", $0); \
+ } \
+ dontprint = 0; \
+ } END { \
+ if ( policymaycome == 1 ) { \
+ printf ("\tmodule %s%s\n", path, policy); \
+ } \
+ }' > $tmpfile
+ if [ ! -r $tmpfile ]; then
+ echo "Could not create temporary file! Aborting."
+ exit -1
+ fi
+ mv -f $tmpfile $grubconf
+}
+
+
+# Display all the labels in a given mapfile
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+showLabels ()
+{
+ mapfile=$1
+ if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ echo "The following labels are available:"
+ let line=1
+ while [ 1 ]; do
+ ITEM=`cat $mapfile | \
+ awk -vline=$line \
+ -vprimary=$primary \
+ '{ \
+ if ($1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == primary ) { \
+ ctr++; \
+ if (ctr == line) { \
+ print $4; \
+ } \
+ } \
+ } END { \
+ }'`
+
+ if [ "$ITEM" == "" ]; then
+ break
+ fi
+ if [ "$secondary" != "NULL" ]; then
+ LABEL=`cat $mapfile | \
+ awk -vitem=$ITEM \
+ '{
+ if ($1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == "CHWALL" && \
+ $4 == item ) { \
+ result = item; \
+ } \
+ } END { \
+ print result \
+ }'`
+ else
+ LABEL=$ITEM
+ fi
+
+ if [ "$LABEL" != "" ]; then
+ echo "$LABEL"
+ found=1
+ fi
+ let line=line+1
+ done
+ if [ "$found" != "1" ]; then
+ echo "No labels found."
+ fi
+}
+
+
+# Get the default SSID given a mapfile and the policy name
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+# 2nd: the name of the policy
+getDefaultSsid ()
+{
+ mapfile=$1
+ pol=$2
+ RES=`cat $mapfile \
+ awk -vpol=$pol \
+ { \
+ if ($1 == "LABEL->SSID" && \
+ $2 == "ANY" && \
+ $3 == pol && \
+ $4 == "DEFAULT" ) {\
+ res=$5; \
+ } \
+ } END { \
+ printf "%04x", strtonum(res) \
+ }'`
+ echo "default NULL mapping is $RES"
+ defaultssid=$RES
+}
+
+
+#Relabel a VM configuration file
+# Parameters
+# 1st: Full or relative path to the VM configuration file
+# 2nd: The label to translate into an ssidref
+# 3rd: Full or relative path to the policy's map file
+# 4th: The mode this function is supposed to operate in:
+# 'relabel' : Relabels the file without querying the user
+# other : Prompts the user whether to proceed
+relabel ()
+{
+ vmfile=$1
+ label=$2
+ mapfile=$3
+ mode=$4
+
+ if [ ! -r "$vmfile" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ if [ ! -w "$vmfile" ]; then
+ echo "Cannot write to vm configuration file $vmfile."
+ return -1
+ fi
+
+ if [ ! -r "$mapfile" ] ; then
+ echo "Cannot read mapping file $mapfile."
+ return -1
+ fi
+
+ # Determine which policy is primary, which sec.
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ # Calculate the primary policy's SSIDREF
+ if [ "$primary" == "NULL" ]; then
+ SSIDLO="0001"
+ else
+ SSIDLO=`cat $mapfile | \
+ awk -vlabel=$label \
+ -vprimary=$primary \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == primary && \
+ $4 == label ) { \
+ result=$5 \
+ } \
+ } END { \
+ if (result != "" ) \
+ {printf "%04x", strtonum(result)}\
+ }'`
+ fi
+
+ # Calculate the secondary policy's SSIDREF
+ if [ "$secondary" == "NULL" ]; then
+ if [ "$primary" == "NULL" ]; then
+ SSIDHI="0001"
+ else
+ SSIDHI="0000"
+ fi
+ else
+ SSIDHI=`cat $mapfile | \
+ awk -vlabel=$label \
+ -vsecondary=$secondary \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == secondary && \
+ $4 == label ) { \
+ result=$5 \
+ } \
+ } END { \
+ if (result != "" ) \
+ {printf "%04x", strtonum(result)}\
+ }'`
+ fi
+
+ if [ "$SSIDLO" == "" -o \
+ "$SSIDHI" == "" ]; then
+ echo "Could not map the given label '$label'."
+ return -1
+ fi
+
+ ACM_POLICY=`cat $mapfile | \
+ awk ' { if ( $1 == "POLICY" ) { \
+ result=$2 \
+ } \
+ } \
+ END { \
+ if (result != "") { \
+ printf result \
+ } \
+ }'`
+
+ if [ "$ACM_POLICY" == "" ]; then
+ echo "Could not find 'POLICY' entry in map file."
+ return -1
+ fi
+
+ SSIDREF="0x$SSIDHI$SSIDLO"
+
+ if [ "$mode" != "relabel" ]; then
+ RES=`cat $vmfile | \
+ awk '{ \
+ if ( substr($1,0,7) == "ssidref" ) {\
+ print $0; \
+ } \
+ }'`
+ if [ "$RES" != "" ]; then
+ echo "Do you want to overwrite the existing mapping
($RES)? (y/N)"
+ read user
+ if [ "$user" != "y" -a "$user" != "Y" ]; then
+ echo "Aborted."
+ return 0
+ fi
+ fi
+ fi
+
+ #Write the output
+ vmtmp1="/tmp/__setlabel.tmp1"
+ vmtmp2="/tmp/__setlabel.tmp2"
+ touch $vmtmp1
+ touch $vmtmp2
+ if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
+ echo "Cannot create temporary files. Aborting."
+ return -1
+ fi
+ RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
+ RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
+ RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
+ echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
+ echo "#ACM_LABEL=$label" >> $vmtmp1
+ echo "ssidref = $SSIDREF" >> $vmtmp1
+ mv -f $vmtmp1 $vmfile
+ rm -rf $vmtmp1 $vmtmp2
+ echo "Mapped label '$label' to ssidref '$SSIDREF'."
+}
+
+
+# Translate an ssidref into its label. This does the reverse lookup
+# to the relabel function above.
+# This function displays the results.
+# Parameters:
+# 1st: The ssidref to translate; must be in the form '0x00010002'
+# 2nd: Full or relative path to the policy's mapfile
+translateSSIDREF ()
+{
+ ssidref=$1
+ mapfile=$2
+
+ if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ if [ "$primary" == "NULL" -a "$secondary" == "NULL" ]; then
+ echo "There are no labels for the NULL policy."
+ return
+ fi
+
+ getSSIDLOHI $ssidref
+ ret=$?
+ if [ $ret -ne 1 ]; then
+ echo "Error while parsing the ssid ref number '$ssidref'."
+ fi;
+
+ let line1=0
+ let line2=0
+ while [ 1 ]; do
+ ITEM1=`cat $mapfile | \
+ awk -vprimary=$primary \
+ -vssidlo=$ssidlo_int \
+ -vline=$line1 \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $3 == primary && \
+ int($5) == ssidlo ) { \
+ if (l == line) { \
+ print $4; \
+ exit; \
+ } \
+ l++; \
+ } \
+ }'`
+
+ ITEM2=`cat $mapfile | \
+ awk -vsecondary=$secondary \
+ -vssidhi=$ssidhi_int \
+ -vline=$line2 \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $3 == secondary && \
+ int($5) == ssidhi ) { \
+ if (l == line) { \
+ print $4; \
+ exit; \
+ } \
+ l++; \
+ } \
+ }'`
+
+ if [ "$secondary" != "NULL" ]; then
+ if [ "$ITEM1" == "" ]; then
+ let line1=0
+ let line2=line2+1
+ else
+ let line1=line1+1
+ fi
+
+ if [ "$ITEM1" == "" -a \
+ "$ITEM2" == "" ]; then
+ echo "Could not determine the referenced label."
+ break
+ fi
+
+ if [ "$ITEM1" == "$ITEM2" ]; then
+ echo "Label: $ITEM1"
+ break
+ fi
+ else
+ if [ "$ITEM1" != "" ]; then
+ echo "Label: $ITEM1"
+ else
+ if [ "$found" == "0" ]; then
+ found=1
+ else
+ break
+ fi
+ fi
+ let line1=line1+1
+ fi
+ done
+}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|