ia64/xen-unstable

view tools/python/xen/xm/cfgbootpolicy.py @ 9835:cf20dbbf5c2b

This patch adds new python access control management scripts, which
integrate into Xen Management and which support the new access control
labels (labels replace the ssidref numbers at the management user
interface).

Signed-off by: Reiner Sailer <sailer@us.ibm.com>
author smh22@firebug.cl.cam.ac.uk
date Mon Apr 24 10:58:25 2006 +0100 (2006-04-24)
parents
children 88dc1ae16d2b
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006 International Business Machines Corp.
16 # Author: Reiner Sailer <sailer@us.ibm.com>
17 #============================================================================
18 """Configuring a security policy into the boot configuration
19 """
21 import sys
22 import traceback
23 import tempfile
24 import os, stat
25 import re
26 import commands
27 import shutil
28 import string
29 from xen.util.security import ACMError, err
30 from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
31 from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
32 from xen.util.security import empty_line_re, binary_name_re, policy_name_re
35 def usage():
36 print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
37 print " Adds a 'module' line to the Xen grub.conf entry"
38 print " so that xen boots into a specific access control"
39 print " policy. If kernelversion is not given, then this"
40 print " script tries to determine it by looking for a grub"
41 print " entry with a line kernel xen.* If there are multiple"
42 print " Xen entries, then it must be called with an explicit"
43 print " version (it will fail otherwise).\n"
44 err("Usage")
48 def determine_kernelversion(user_specified):
49 within_xen_title = 0
50 within_xen_entry = 0
51 version_list = []
52 guess_version = None
54 grub_fd = open(boot_filename)
55 for line in grub_fd:
56 if xen_title_re.match(line):
57 within_xen_title = 1
58 elif within_xen_title and xen_kernel_re.match(line):
59 within_xen_entry = 1
60 elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
61 for i in line.split():
62 if (i.find("vmlinuz-") >= 0):
63 # skip start until "vmlinuz-"
64 guess_version = i[i.find("vmlinuz-") + len("vmlinuz-"):]
65 if user_specified:
66 if (guess_version == user_specified):
67 version_list.append(guess_version)
68 else:
69 version_list.append(guess_version)
70 elif len(line.split()) > 0:
71 if line.split()[0] == "title":
72 within_xen_title = 0
73 within_xen_entry = 0
74 if len(version_list) > 1:
75 err("Cannot decide between entries for kernels: " + version_list)
76 elif len(version_list) == 0:
77 err("Cannot find a boot entry candidate (please create a Xen boot entry first).")
78 else:
79 return version_list[0]
83 def insert_policy(boot_file, kernel_version, policy_name):
84 """
85 inserts policy binary file as last line of the grub entry
86 matching the kernel_version version
87 """
88 within_xen_title = 0
89 within_xen_entry = 0
90 insert_at_end_of_entry = 0
91 path_prefix = ''
92 done = False
93 (tmp_fd, tmp_grub) = tempfile.mkstemp()
94 #follow symlink since menue.lst might be linked to grub.conf
95 if stat.S_ISLNK(os.lstat(boot_file)[stat.ST_MODE]):
96 new_name = os.readlink(boot_file)
97 if new_name[0] == "/":
98 boot_file = new_name
99 else:
100 path = boot_file.split('/')
101 path[len(path)-1] = new_name
102 boot_file = '/'.join(path)
103 if not os.path.exists(boot_file):
104 err("Boot file \'" + boot_file + "\' not found.")
105 grub_fd = open(boot_file)
106 for line in grub_fd:
107 if xen_title_re.match(line):
108 within_xen_title = 1
109 elif within_xen_title and xen_kernel_re.match(line):
110 within_xen_entry = 1
111 elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
112 for i in line.split():
113 if (i.find("vmlinuz-") >= 0):
114 if kernel_version == i[i.find("vmlinuz-") + len("vmlinuz-"):]:
115 insert_at_end_of_entry = 1
116 path_prefix = i[0:i.find("vmlinuz-")]
117 elif any_module_re.match(line) and insert_at_end_of_entry:
118 if binary_name_re.match(line):
119 #delete existing policy module line
120 line=''
121 elif any_title_re.match(line):
122 within_xen_title = 0
123 within_xen_entry = 0
125 if (empty_line_re.match(line) or any_title_re.match(line)) and insert_at_end_of_entry:
126 #newline or new title: we insert the policy module line here
127 os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
128 insert_at_end_of_entry = 0
129 #write the line that was read (except potential existing policy entry)
130 os.write(tmp_fd, line)
132 if insert_at_end_of_entry:
133 #last entry, no empty line at end of file
134 os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
136 #temp file might be destroyed when closing it, first copy ...
137 shutil.move(boot_file, boot_file+"_save")
138 shutil.copyfile(tmp_grub, boot_file)
139 os.close(tmp_fd)
140 #temp file did not disappear on my system ...
141 try:
142 os.remove(tmp_grub)
143 except:
144 pass
148 def main(argv):
149 try:
150 user_kver = None
151 policy = None
152 if len(argv) == 2:
153 policy = argv[1]
154 elif len(argv) == 3:
155 policy = argv[1]
156 user_kver = argv[2]
157 else:
158 usage()
160 if not policy_name_re.match(policy):
161 err("Illegal policy name \'" + policy + "\'")
163 policy_file = policy_dir_prefix + "/" + string.join(string.split(policy, "."), "/")
164 src_binary_policy_file = policy_file + ".bin"
165 #check if .bin exists or if policy file exists
166 if not os.path.isfile(src_binary_policy_file):
167 if not os.path.isfile(policy_file + "-security_policy.xml"):
168 err("Unknown policy \'" + policy +"\'")
169 else:
170 err("Cannot find binary file for policy \'" + policy +
171 "\'. Please use makepolicy to create binary file.")
172 dst_binary_policy_file = "/boot/" + policy + ".bin"
173 shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
175 kernel_version = determine_kernelversion(user_kver)
176 insert_policy(boot_filename, kernel_version, policy)
177 print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
179 except ACMError:
180 pass
181 except:
182 traceback.print_exc(limit=1)
186 if __name__ == '__main__':
187 main(sys.argv)