ia64/xen-unstable

view tools/python/xen/xm/addlabel.py @ 10720:8922c1fbe684

[XM][ACM] Add xm subcommands to work with security resource labels.

This patch adds new xm subcommands to support working with resource
labels. The new subcommands are 'xm resources', 'xm rmlabel', 'xm
getlabel' and 'xm dry-run'. In addition, the 'xm addlabel' subcommand
now uses an updated syntax to support labeling both domains and
resources. See the xm man page for details on each subcommand.

Beyond the new subcommands, this patch allows users to immediately see
when security checks will fail by pushing some basic security checking
into the beginning of 'xm create' and 'xm block-attach'. ACM security
attributes for block devices are added to XenStore in order to support
the final security enforcement, which will be performed in the kernel
and included in a separate patch.

Signed-off-by: Bryan D. Payne <bdpayne@us.ibm.com>
Signed-off-by: Reiner Sailer <sailer@us.ibm.com>
author kfraser@localhost.localdomain
date Mon Jul 10 17:18:07 2006 +0100 (2006-07-10)
parents 0de8a4a023d0
children 956e9aaf88c9
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 # Author: Bryan D. Payne <bdpayne@us.ibm.com>
18 #============================================================================
20 """Labeling a domain configuration file or a resoruce.
21 """
22 import sys, os
23 import string
24 import traceback
25 from xen.util import dictio
26 from xen.util import security
28 def usage():
29 print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]"
30 print " xm addlabel <label> res <resource> [<policy>]\n"
31 print " This program adds an acm_label entry into the 'configfile'"
32 print " for a domain or to the global resource label file for a"
33 print " resource. It derives the policy from the running hypervisor"
34 print " if it is not given (optional parameter). If a label already"
35 print " exists for the given domain or resource, then addlabel fails.\n"
38 def validate_config_file(configfile):
39 """Performs a simple sanity check on the configuration file passed on
40 the command line. We basically just want to make sure that it's
41 not a domain image file so we check for a few configuration values
42 and then we are satisfied. Returned 1 on success, otherwise 0.
43 """
44 # read in the config file
45 globs = {}
46 locs = {}
47 try:
48 execfile(configfile, globs, locs)
49 except:
50 print "Invalid configuration file."
51 return 0
53 # sanity check on the data from the file
54 count = 0
55 required = ['kernel', 'memory', 'name']
56 for (k, v) in locs.items():
57 if k in required:
58 count += 1
59 if count != 3:
60 print "Invalid configuration file."
61 return 0
62 else:
63 return 1
66 def add_resource_label(label, resource, policyref):
67 """Adds a resource label to the global resource label file.
68 """
69 # sanity check: make sure this label can be instantiated later on
70 ssidref = security.label2ssidref(label, policyref, 'res')
72 # sanity check on resource name
73 (type, file) = resource.split(":")
74 if type == "phy":
75 file = "/dev/" + file
76 if not os.path.exists(file):
77 print "Invalid resource '"+resource+"'"
78 return
80 # see if this resource is already in the file
81 access_control = {}
82 file = security.res_label_filename
83 try:
84 access_control = dictio.dict_read("resources", file)
85 except:
86 print "Resource file not found, creating new file at:"
87 print "%s" % (file)
89 if access_control.has_key(resource):
90 security.err("This resource is already labeled.")
92 # write the data to file
93 new_entry = { resource : tuple([policyref, label]) }
94 access_control.update(new_entry)
95 dictio.dict_write(access_control, "resources", file)
98 def add_domain_label(label, configfile, policyref):
99 # sanity checks: make sure this label can be instantiated later on
100 ssidref = security.label2ssidref(label, policyref, 'dom')
102 new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label)
103 if not os.path.isfile(configfile):
104 security.err("Configuration file \'" + configfile + "\' not found.")
105 config_fd = open(configfile, "ra+")
106 for line in config_fd:
107 if not security.access_control_re.match(line):
108 continue
109 config_fd.close()
110 security.err("Config file \'" + configfile + "\' is already labeled.")
111 config_fd.write(new_label)
112 config_fd.close()
115 def main (argv):
116 try:
117 policyref = None
118 if len(argv) not in [4,5]:
119 usage()
120 return
122 label = argv[1]
124 if len(argv) == 5:
125 policyref = argv[4]
126 elif security.on():
127 policyref = security.active_policy
128 else:
129 security.err("No active policy. Policy must be specified in command line.")
131 if argv[2].lower() == "dom":
132 configfile = argv[3]
133 if configfile[0] != '/':
134 for prefix in [".", "/etc/xen"]:
135 configfile = prefix + "/" + configfile
136 if os.path.isfile(configfile):
137 fd = open(configfile, "rb")
138 break
139 if not validate_config_file(configfile):
140 usage()
141 else:
142 add_domain_label(label, configfile, policyref)
143 elif argv[2].lower() == "res":
144 resource = argv[3]
145 add_resource_label(label, resource, policyref)
146 else:
147 usage()
149 except security.ACMError:
150 traceback.print_exc(limit=1)
153 if __name__ == '__main__':
154 main(sys.argv)