ia64/xen-unstable

view tools/security/labelfuncs.sh @ 6812:26cf3cfd3bed

Switch vcpu hotplugging to use xstransact.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Tue Sep 13 17:31:13 2005 +0000 (2005-09-13)
parents 291e816acbf4
children b2f4823b6ff0 b35215021b32 9af349b055e5 3233e7ecfa9f
line source
1 # *
2 # * labelfuncs.sh
3 # *
4 # * Copyright (C) 2005 IBM Corporation
5 # *
6 # * Authors:
7 # * Stefan Berger <stefanb@us.ibm.com>
8 # *
9 # * This program is free software; you can redistribute it and/or
10 # * modify it under the terms of the GNU General Public License as
11 # * published by the Free Software Foundation, version 2 of the
12 # * License.
13 # *
14 # *
15 # * A collection of functions to handle polcies, mapfiles,
16 # * and ssidrefs.
17 #
20 # Find the mapfile given a policy nmame
21 # Parameters:
22 # 1st : the name of the policy whose map file is to be found, i.e.,
23 # chwall
24 # Results:
25 # The variable mapfile will hold the realtive path to the mapfile
26 # for the given policy.
27 # In case the mapfile could be found, the functions returns a '1',
28 # a '0' otherwise.
29 findMapFile ()
30 {
31 mapfile="./$1.map"
32 if [ -r "$mapfile" ]; then
33 return 1
34 fi
36 mapfile="./policies/$1/$1.map"
37 if [ -r "$mapfile" ]; then
38 return 1
39 fi
41 return 0
42 }
45 # Determine the name of the primary policy
46 # Parameters
47 # 1st : the path to the mapfile; the path may be relative
48 # to the current directory
49 # Results
50 # The variable primary will hold the name of the primary policy
51 getPrimaryPolicy ()
52 {
53 mapfile=$1
54 primary=`cat $mapfile | \
55 awk ' \
56 { \
57 if ( $1 == "PRIMARY" ) { \
58 res=$2; \
59 } \
60 } END { \
61 print res; \
62 } '`
63 }
66 # Determine the name of the secondary policy
67 # Parameters
68 # 1st : the path to the mapfile; the path may be relative
69 # to the current directory
70 # Results
71 # The variable secondary will hold the name of the secondary policy
72 getSecondaryPolicy ()
73 {
74 mapfile=$1
75 secondary=`cat $mapfile | \
76 awk ' \
77 { \
78 if ( $1 == "SECONDARY" ) { \
79 res=$2; \
80 } \
81 } END { \
82 print res; \
83 } '`
84 }
87 #Return where the grub.conf file is.
88 #I only know of one place it can be.
89 findGrubConf()
90 {
91 grubconf="/boot/grub/grub.conf"
92 if [ -w $grubconf ]; then
93 return 1
94 fi
95 if [ -r $grubconf ]; then
96 return 2
97 fi
98 return 0
99 }
102 # This function sets the global variable 'linux'
103 # to the name and version of the Linux kernel that was compiled
104 # for domain 0.
105 # If this variable could not be found, the variable 'linux'
106 # will hold a pattern
107 # Parameters:
108 # 1st: the path to reach the root directory of the XEN build tree
109 # where linux-*-xen0 is located at
110 # Results:
111 # The variable linux holds then name and version of the compiled
112 # kernel, i.e., 'vmlinuz-2.6.12-xen0'
113 getLinuxVersion ()
114 {
115 path=$1
116 linux=""
117 for f in $path/linux-*-xen0 ; do
118 versionfile=$f/include/linux/version.h
119 if [ -r $versionfile ]; then
120 lnx=`cat $versionfile | \
121 grep UTS_RELEASE | \
122 awk '{ \
123 len=length($3); \
124 print substr($3,2,len-2) }'`
125 fi
126 if [ "$lnx" != "" ]; then
127 linux="[./0-9a-zA-z]*$lnx"
128 return;
129 fi
130 done
132 #Last resort.
133 linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
134 }
137 # Find out with which policy the hypervisor was booted with.
138 # Parameters
139 # 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
140 #
141 findPolicyInGrub ()
142 {
143 grubconf=$1
144 linux=`uname -r`
145 policy=`cat $grubconf | \
146 awk -vlinux=$linux '{ \
147 if ( $1 == "title" ) { \
148 kernelfound = 0; \
149 policymaycome = 0; \
150 } \
151 else if ( $1 == "kernel" ) { \
152 if ( match($2,"xen.gz$") ) { \
153 pathlen=RSTART; \
154 kernelfound = 1; \
155 } \
156 } \
157 else if ( $1 == "module" && \
158 kernelfound == 1 && \
159 match($2,linux) ) { \
160 policymaycome = 1; \
161 } \
162 else if ( $1 == "module" && \
163 kernelfound == 1 && \
164 policymaycome == 1 && \
165 match($2,"[0-9a-zA-Z_]*.bin$") ) { \
166 policymaycome = 0; \
167 kernelfound = 0; \
168 polname = substr($2,pathlen); \
169 len=length(polname); \
170 polname = substr(polname,0,len-4); \
171 } \
172 } END { \
173 print polname \
174 }'`
175 }
178 # Get the SSID of a domain
179 # Parameters:
180 # 1st : domain ID, i.e. '1'
181 # Results
182 # If the ssid could be found, the variable 'ssid' will hold
183 # the currently used ssid in the hex format, i.e., '0x00010001'.
184 # The funtion returns '1' on success, '0' on failure
185 getSSIDUsingSecpolTool ()
186 {
187 domid=$1
188 export PATH=$PATH:.
189 ssid=`secpol_tool getssid -d $domid -f | \
190 grep -E "SSID:" | \
191 awk '{ print $4 }'`
193 if [ "$ssid" != "" ]; then
194 return 1
195 fi
196 return 0
197 }
200 # Break the ssid identifier into its high and low values,
201 # which are equal to the secondary and primary policy references.
202 # Parameters:
203 # 1st: ssid to break into high and low value, i.e., '0x00010002'
204 # Results:
205 # The variable ssidlo_int and ssidhi_int will hold the low and
206 # high ssid values as integers.
207 getSSIDLOHI ()
208 {
209 ssid=$1
210 ssidlo_int=`echo $ssid | awk \
211 '{ \
212 len=length($0); \
213 beg=substr($0,1,2); \
214 if ( beg == "0x" ) { \
215 dig = len - 2; \
216 if (dig <= 0) { \
217 exit; \
218 } \
219 if (dig > 4) { \
220 dig=4; \
221 } \
222 lo=sprintf("0x%s",substr($0,len-dig+1,dig)); \
223 print strtonum(lo);\
224 } else { \
225 lo=strtonum($0); \
226 if (lo < 65536) { \
227 print lo; \
228 } else { \
229 hi=lo; \
230 hi2= (hi / 65536);\
231 hi2_str=sprintf("%d",hi2); \
232 hi2=strtonum(hi2_str);\
233 lo=hi-(hi2*65536); \
234 printf("%d",lo); \
235 } \
236 } \
237 }'`
238 ssidhi_int=`echo $ssid | awk \
239 '{ \
240 len=length($0); \
241 beg=substr($0,1,2); \
242 if ( beg == "0x" ) { \
243 dig = len - 2; \
244 if (dig <= 0 || \
245 dig > 8) { \
246 exit; \
247 } \
248 if (dig < 4) { \
249 print 0; \
250 exit; \
251 } \
252 dig -= 4; \
253 hi=sprintf("0x%s",substr($0,len-4-dig+1,dig)); \
254 print strtonum(hi);\
255 } else { \
256 hi=strtonum($0); \
257 if (hi >= 65536) { \
258 hi = hi / 65536; \
259 printf ("%d",hi);\
260 } else { \
261 printf ("0"); \
262 } \
263 } \
264 }'`
265 if [ "$ssidhi_int" == "" -o \
266 "$ssidlo_int" == "" ]; then
267 return 0;
268 fi
269 return 1
270 }
273 #Update the grub configuration file.
274 #Search for existing entries and replace the current
275 #policy entry with the policy passed to this script
276 #
277 #Arguments passed to this function
278 # 1st : the grub configuration file with full path
279 # 2nd : the binary policy file name, i.e. chwall.bin
280 # 3rd : the name or pattern of the linux kernel name to match
281 # (this determines where the module entry will be made)
282 #
283 # The algorithm here is based on pattern matching
284 # and is working correctly if
285 # - under a title a line beginning with 'kernel' is found
286 # whose following item ends with "xen.gz"
287 # Example: kernel /xen.gz dom0_mem=....
288 # - a module line matching the 3rd parameter is found
289 #
290 updateGrub ()
291 {
292 grubconf=$1
293 policyfile=$2
294 linux=$3
296 tmpfile="/tmp/new_grub.conf"
298 cat $grubconf | \
299 awk -vpolicy=$policyfile \
300 -vlinux=$linux '{ \
301 if ( $1 == "title" ) { \
302 kernelfound = 0; \
303 if ( policymaycome == 1 ){ \
304 printf ("\tmodule %s%s\n", path, policy); \
305 } \
306 policymaycome = 0; \
307 } \
308 else if ( $1 == "kernel" ) { \
309 if ( match($2,"xen.gz$") ) { \
310 path=substr($2,1,RSTART-1); \
311 kernelfound = 1; \
312 } \
313 } \
314 else if ( $1 == "module" && \
315 kernelfound == 1 && \
316 match($2,linux) ) { \
317 policymaycome = 1; \
318 } \
319 else if ( $1 == "module" && \
320 kernelfound == 1 && \
321 policymaycome == 1 && \
322 match($2,"[0-9a-zA-Z]*.bin$") ) { \
323 printf ("\tmodule %s%s\n", path, policy); \
324 policymaycome = 0; \
325 kernelfound = 0; \
326 dontprint = 1; \
327 } \
328 else if ( $1 == "" && \
329 kernelfound == 1 && \
330 policymaycome == 1) { \
331 dontprint = 1; \
332 } \
333 if (dontprint == 0) { \
334 printf ("%s\n", $0); \
335 } \
336 dontprint = 0; \
337 } END { \
338 if ( policymaycome == 1 ) { \
339 printf ("\tmodule %s%s\n", path, policy); \
340 } \
341 }' > $tmpfile
342 if [ ! -r $tmpfile ]; then
343 echo "Could not create temporary file! Aborting."
344 exit -1
345 fi
346 mv -f $tmpfile $grubconf
347 }
350 # Display all the labels in a given mapfile
351 # Parameters
352 # 1st: Full or relative path to the policy's mapfile
353 showLabels ()
354 {
355 mapfile=$1
356 if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
357 echo "Cannot read from vm configuration file $vmfile."
358 return -1
359 fi
361 getPrimaryPolicy $mapfile
362 getSecondaryPolicy $mapfile
364 echo "The following labels are available:"
365 let line=1
366 while [ 1 ]; do
367 ITEM=`cat $mapfile | \
368 awk -vline=$line \
369 -vprimary=$primary \
370 '{ \
371 if ($1 == "LABEL->SSID" && \
372 $2 == "VM" && \
373 $3 == primary ) { \
374 ctr++; \
375 if (ctr == line) { \
376 print $4; \
377 } \
378 } \
379 } END { \
380 }'`
382 if [ "$ITEM" == "" ]; then
383 break
384 fi
385 if [ "$secondary" != "NULL" ]; then
386 LABEL=`cat $mapfile | \
387 awk -vitem=$ITEM \
388 '{
389 if ($1 == "LABEL->SSID" && \
390 $2 == "VM" && \
391 $3 == "CHWALL" && \
392 $4 == item ) { \
393 result = item; \
394 } \
395 } END { \
396 print result \
397 }'`
398 else
399 LABEL=$ITEM
400 fi
402 if [ "$LABEL" != "" ]; then
403 echo "$LABEL"
404 found=1
405 fi
406 let line=line+1
407 done
408 if [ "$found" != "1" ]; then
409 echo "No labels found."
410 fi
411 }
414 # Get the default SSID given a mapfile and the policy name
415 # Parameters
416 # 1st: Full or relative path to the policy's mapfile
417 # 2nd: the name of the policy
418 getDefaultSsid ()
419 {
420 mapfile=$1
421 pol=$2
422 RES=`cat $mapfile \
423 awk -vpol=$pol \
424 { \
425 if ($1 == "LABEL->SSID" && \
426 $2 == "ANY" && \
427 $3 == pol && \
428 $4 == "DEFAULT" ) {\
429 res=$5; \
430 } \
431 } END { \
432 printf "%04x", strtonum(res) \
433 }'`
434 echo "default NULL mapping is $RES"
435 defaultssid=$RES
436 }
439 #Relabel a VM configuration file
440 # Parameters
441 # 1st: Full or relative path to the VM configuration file
442 # 2nd: The label to translate into an ssidref
443 # 3rd: Full or relative path to the policy's map file
444 # 4th: The mode this function is supposed to operate in:
445 # 'relabel' : Relabels the file without querying the user
446 # other : Prompts the user whether to proceed
447 relabel ()
448 {
449 vmfile=$1
450 label=$2
451 mapfile=$3
452 mode=$4
454 if [ ! -r "$vmfile" ]; then
455 echo "Cannot read from vm configuration file $vmfile."
456 return -1
457 fi
459 if [ ! -w "$vmfile" ]; then
460 echo "Cannot write to vm configuration file $vmfile."
461 return -1
462 fi
464 if [ ! -r "$mapfile" ] ; then
465 echo "Cannot read mapping file $mapfile."
466 return -1
467 fi
469 # Determine which policy is primary, which sec.
470 getPrimaryPolicy $mapfile
471 getSecondaryPolicy $mapfile
473 # Calculate the primary policy's SSIDREF
474 if [ "$primary" == "NULL" ]; then
475 SSIDLO="0001"
476 else
477 SSIDLO=`cat $mapfile | \
478 awk -vlabel=$label \
479 -vprimary=$primary \
480 '{ \
481 if ( $1 == "LABEL->SSID" && \
482 $2 == "VM" && \
483 $3 == primary && \
484 $4 == label ) { \
485 result=$5 \
486 } \
487 } END { \
488 if (result != "" ) \
489 {printf "%04x", strtonum(result)}\
490 }'`
491 fi
493 # Calculate the secondary policy's SSIDREF
494 if [ "$secondary" == "NULL" ]; then
495 if [ "$primary" == "NULL" ]; then
496 SSIDHI="0001"
497 else
498 SSIDHI="0000"
499 fi
500 else
501 SSIDHI=`cat $mapfile | \
502 awk -vlabel=$label \
503 -vsecondary=$secondary \
504 '{ \
505 if ( $1 == "LABEL->SSID" && \
506 $2 == "VM" && \
507 $3 == secondary && \
508 $4 == label ) { \
509 result=$5 \
510 } \
511 } END { \
512 if (result != "" ) \
513 {printf "%04x", strtonum(result)}\
514 }'`
515 fi
517 if [ "$SSIDLO" == "" -o \
518 "$SSIDHI" == "" ]; then
519 echo "Could not map the given label '$label'."
520 return -1
521 fi
523 ACM_POLICY=`cat $mapfile | \
524 awk ' { if ( $1 == "POLICY" ) { \
525 result=$2 \
526 } \
527 } \
528 END { \
529 if (result != "") { \
530 printf result \
531 } \
532 }'`
534 if [ "$ACM_POLICY" == "" ]; then
535 echo "Could not find 'POLICY' entry in map file."
536 return -1
537 fi
539 SSIDREF="0x$SSIDHI$SSIDLO"
541 if [ "$mode" != "relabel" ]; then
542 RES=`cat $vmfile | \
543 awk '{ \
544 if ( substr($1,0,7) == "ssidref" ) {\
545 print $0; \
546 } \
547 }'`
548 if [ "$RES" != "" ]; then
549 echo "Do you want to overwrite the existing mapping ($RES)? (y/N)"
550 read user
551 if [ "$user" != "y" -a "$user" != "Y" ]; then
552 echo "Aborted."
553 return 0
554 fi
555 fi
556 fi
558 #Write the output
559 vmtmp1="/tmp/__setlabel.tmp1"
560 vmtmp2="/tmp/__setlabel.tmp2"
561 touch $vmtmp1
562 touch $vmtmp2
563 if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
564 echo "Cannot create temporary files. Aborting."
565 return -1
566 fi
567 RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
568 RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
569 RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
570 echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
571 echo "#ACM_LABEL=$label" >> $vmtmp1
572 echo "ssidref = $SSIDREF" >> $vmtmp1
573 mv -f $vmtmp1 $vmfile
574 rm -rf $vmtmp1 $vmtmp2
575 echo "Mapped label '$label' to ssidref '$SSIDREF'."
576 }
579 # Translate an ssidref into its label. This does the reverse lookup
580 # to the relabel function above.
581 # This function displays the results.
582 # Parameters:
583 # 1st: The ssidref to translate; must be in the form '0x00010002'
584 # 2nd: Full or relative path to the policy's mapfile
585 translateSSIDREF ()
586 {
587 ssidref=$1
588 mapfile=$2
590 if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
591 echo "Cannot read from vm configuration file $vmfile."
592 return -1
593 fi
595 getPrimaryPolicy $mapfile
596 getSecondaryPolicy $mapfile
598 if [ "$primary" == "NULL" -a "$secondary" == "NULL" ]; then
599 echo "There are no labels for the NULL policy."
600 return
601 fi
603 getSSIDLOHI $ssidref
604 ret=$?
605 if [ $ret -ne 1 ]; then
606 echo "Error while parsing the ssid ref number '$ssidref'."
607 fi;
609 let line1=0
610 let line2=0
611 while [ 1 ]; do
612 ITEM1=`cat $mapfile | \
613 awk -vprimary=$primary \
614 -vssidlo=$ssidlo_int \
615 -vline=$line1 \
616 '{ \
617 if ( $1 == "LABEL->SSID" && \
618 $3 == primary && \
619 int($5) == ssidlo ) { \
620 if (l == line) { \
621 print $4; \
622 exit; \
623 } \
624 l++; \
625 } \
626 }'`
628 ITEM2=`cat $mapfile | \
629 awk -vsecondary=$secondary \
630 -vssidhi=$ssidhi_int \
631 -vline=$line2 \
632 '{ \
633 if ( $1 == "LABEL->SSID" && \
634 $3 == secondary && \
635 int($5) == ssidhi ) { \
636 if (l == line) { \
637 print $4; \
638 exit; \
639 } \
640 l++; \
641 } \
642 }'`
644 if [ "$secondary" != "NULL" ]; then
645 if [ "$ITEM1" == "" ]; then
646 let line1=0
647 let line2=line2+1
648 else
649 let line1=line1+1
650 fi
652 if [ "$ITEM1" == "" -a \
653 "$ITEM2" == "" ]; then
654 echo "Could not determine the referenced label."
655 break
656 fi
658 if [ "$ITEM1" == "$ITEM2" ]; then
659 echo "Label: $ITEM1"
660 break
661 fi
662 else
663 if [ "$ITEM1" != "" ]; then
664 echo "Label: $ITEM1"
665 else
666 if [ "$found" == "0" ]; then
667 found=1
668 else
669 break
670 fi
671 fi
672 let line1=line1+1
673 fi
674 done
675 }