#============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public # License as published by the Free Software Foundation. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ # Copyright (C) 2007 International Business Machines Corp. # Author: Stefan Berger #============================================================================ """Get the managed policy of the system. """ import os import sys import base64 import struct import xen.util.xsm.xsm as security from xen.util import xsconstants from xen.util.xsm.acm.acm import install_policy_dir_prefix from xen.util.acmpolicy import ACMPolicy, \ ACM_EVTCHN_SHARING_VIOLATION,\ ACM_GNTTAB_SHARING_VIOLATION, \ ACM_DOMAIN_LOOKUP, \ ACM_CHWALL_CONFLICT, \ ACM_SSIDREF_IN_USE from xen.xm.opts import OptionError from xen.xm import main as xm_main from xen.xm.getpolicy import getpolicy from xen.xm.main import server def help(): return """ Usage: xm setpolicy Set the policy managed by xend. The only policytype that is currently supported is 'ACM'. The filename of the policy is the policy name plus the suffic '-security_policy.xml'. The location of the policy file is either the the current directory or '/etc/xen/acm-security/policies'. """ def build_hv_error_message(errors): """ Build a message from the error codes return by the hypervisor. """ txt = "Hypervisor reported errors:" i = 0 while i + 7 < len(errors): code, data = struct.unpack("!ii", errors[i:i+8]) err_msgs = { ACM_EVTCHN_SHARING_VIOLATION : \ ["event channel sharing violation between domains",2], ACM_GNTTAB_SHARING_VIOLATION : \ ["grant table sharing violation between domains",2], ACM_DOMAIN_LOOKUP : \ ["domain lookup",1], ACM_CHWALL_CONFLICT : \ ["Chinese Wall conflict between domains",2], ACM_SSIDREF_IN_USE : \ ["A domain used SSIDREF",1], } num = err_msgs[code][1] if num == 1: txt += "%s %d" % (err_msgs[code][0], data) else: txt += "%s %d and %d" % (err_msgs[code][0], data >> 16 , data & 0xffff) i += 8 return txt def setpolicy(policytype, policy_name, flags, overwrite): if policytype.upper() == xsconstants.ACM_POLICY_ID: xs_type = xsconstants.XS_POLICY_ACM for prefix in [ './', install_policy_dir_prefix+"/" ]: policy_file = prefix + "/".join(policy_name.split(".")) + \ "-security_policy.xml" if os.path.exists(policy_file): break try: f = open(policy_file,"r") xml = f.read() f.close() except: raise OptionError("Could not read policy file from current" " directory or '%s'." % install_policy_dir_prefix) if xm_main.serverType == xm_main.SERVER_XEN_API: if xs_type != int(server.xenapi.XSPolicy.get_xstype()): raise security.XSMError("ACM policy type not supported.") try: policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type, xml, flags, overwrite) except Exception, e: raise security.XSMError("An error occurred setting the " "policy: %s" % str(e)) xserr = int(policystate['xserr']) if xserr != xsconstants.XSERR_SUCCESS: txt = "An error occurred trying to set the policy: %s." % \ xsconstants.xserr2string(abs(xserr)) errors = policystate['errors'] if len(errors) > 0: txt += " " + build_hv_error_message(base64.b64decode(errors)) raise security.XSMError(txt) else: print "Successfully set the new policy." getpolicy(False) else: # Non-Xen-API call. if xs_type != server.xend.security.get_xstype(): raise security.XSMError("ACM policy type not supported.") rc, errors = server.xend.security.set_policy(xs_type, xml, flags, overwrite) if rc != xsconstants.XSERR_SUCCESS: txt = "An error occurred trying to set the policy: %s." % \ xsconstants.xserr2string(abs(rc)) if len(errors) > 0: txt += " " + build_hv_error_message( base64.b64decode(errors)) raise security.XSMError(txt) else: print "Successfully set the new policy." getpolicy(False) else: raise OptionError("Unsupported policytype '%s'." % policytype) def main(argv): if len(argv) < 3: raise OptionError("Need at least 3 arguments.") if "-?" in argv: help() return policytype = argv[1] policy_name = argv[2] flags = xsconstants.XS_INST_LOAD | xsconstants.XS_INST_BOOT overwrite = True setpolicy(policytype, policy_name, flags, overwrite) if __name__ == '__main__': try: main(sys.argv) except Exception, e: sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) a> 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
/*
 * swlib.h: Switch configuration API (user space part)
 *
 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *

Usage of the library functions:

  The main datastructure for a switch is the struct switch_device
  To get started, you first need to use switch_connect() to probe
  for switches and allocate an instance of this struct.

  There are two possible usage modes:
    dev = switch_connect("eth0");
      - this call will look for a switch registered for the linux device
  	  "eth0" and only allocate a switch_device for this particular switch.

    dev = switch_connect(NULL)
      - this will return one switch_device struct for each available
  	  switch. The switch_device structs are chained with by ->next pointer

  Then to query a switch for all available attributes, use:
    swlib_scan(dev);

  All allocated datastructures for the switch_device struct can be freed with
    swlib_free(dev);
  or
    swlib_free_all(dev);

  The latter traverses a whole chain of switch_device structs and frees them all

  Switch attributes (struct switch_attr) are divided into three groups:
    dev->ops:
      - global settings
    dev->port_ops:
      - per-port settings
    dev->vlan_ops:
      - per-vlan settings

  switch_lookup_attr() is a small helper function to locate attributes
  by name.

  switch_set_attr() and switch_get_attr() can alter or request the values
  of attributes.

Usage of the switch_attr struct:

  ->atype: attribute group, one of:
    - SWLIB_ATTR_GROUP_GLOBAL
    - SWLIB_ATTR_GROUP_VLAN
    - SWLIB_ATTR_GROUP_PORT

  ->id: identifier for the attribute

  ->type: data type, one of:
    - SWITCH_TYPE_INT
    - SWITCH_TYPE_STRING
    - SWITCH_TYPE_PORT

  ->name: short name of the attribute
  ->description: longer description
  ->next: pointer to the next attribute of the current group


Usage of the switch_val struct:

  When setting attributes, following members of the struct switch_val need
  to be set up:

    ->len (for attr->type == SWITCH_TYPE_PORT)
    ->port_vlan:
      - port number (for attr->atype == SWLIB_ATTR_GROUP_PORT), or:
      - vlan number (for attr->atype == SWLIB_ATTR_GROUP_VLAN)
    ->value.i (for attr->type == SWITCH_TYPE_INT)
    ->value.s (for attr->type == SWITCH_TYPE_STRING)
      - owned by the caller, not stored in the library internally
    ->value.ports (for attr->type == SWITCH_TYPE_PORT)
      - must point to an array of at lest val->len * sizeof(struct switch_port)

  When getting string attributes, val->value.s must be freed by the caller
  When getting port list attributes, an internal static buffer is used,
  which changes from call to call.

 */

#ifndef __SWLIB_H
#define __SWLIB_H

enum swlib_attr_group {
	SWLIB_ATTR_GROUP_GLOBAL,
	SWLIB_ATTR_GROUP_VLAN,
	SWLIB_ATTR_GROUP_PORT,
};

enum swlib_port_flags {
	SWLIB_PORT_FLAG_TAGGED = (1 << 0),
};


struct switch_dev;
struct switch_attr;
struct switch_port;
struct switch_val;
struct uci_package;

struct switch_dev {
	int id;
	const char *name;
	const char *dev_name;
	int ports;
	int vlans;
	struct switch_attr *ops;
	struct switch_attr *port_ops;
	struct switch_attr *vlan_ops;
	struct switch_dev *next;
	void *priv;
};

struct switch_val {
	struct switch_attr *attr;
	int len;
	int err;
	int port_vlan;
	union {
		const char *s;
		int i;
		struct switch_port *ports;
	} value;
};

struct switch_attr {
	struct switch_dev *dev;
	int atype;
	int id;
	int type;
	const char *name;
	const char *description;
	struct switch_attr *next;
};

struct switch_port {
	unsigned int id;
	unsigned int flags;
};

/**
 * swlib_connect: connect to the switch through netlink
 * @name: name of the ethernet interface,
 *
 * if name is NULL, it connect and builds a chain of all switches
 */
struct switch_dev *swlib_connect(const char *name);

/**
 * swlib_free: free all dynamically allocated data for the switch connection
 * @dev: switch device struct
 *
 * all members of a switch device chain (generated by swlib_connect(NULL))
 * must be freed individually
 */
void swlib_free(struct switch_dev *dev);

/**
 * swlib_free_all: run swlib_free on all devices in the chain
 * @dev: switch device struct
 */
void swlib_free_all(struct switch_dev *dev);

/**
 * swlib_scan: probe the switch driver for available commands/attributes
 * @dev: switch device struct
 */
int swlib_scan(struct switch_dev *dev);

/**
 * swlib_lookup_attr: look up a switch attribute
 * @dev: switch device struct
 * @type: global, port or vlan
 * @name: name of the attribute
 */
struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
		enum swlib_attr_group atype, const char *name);

/**
 * swlib_set_attr: set the value for an attribute
 * @dev: switch device struct
 * @attr: switch attribute struct
 * @val: attribute value pointer
 * returns 0 on success
 */
int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
		struct switch_val *val);

/**
 * swlib_set_attr_string: set the value for an attribute with type conversion
 * @dev: switch device struct
 * @attr: switch attribute struct
 * @port_vlan: port or vlan (if applicable)
 * @str: string value
 * returns 0 on success
 */
int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr,
		int port_vlan, const char *str);

/**
 * swlib_get_attr: get the value for an attribute
 * @dev: switch device struct
 * @attr: switch attribute struct
 * @val: attribute value pointer
 * returns 0 on success
 * for string attributes, the result string must be freed by the caller
 */
int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
		struct switch_val *val);

/**
 * swlib_apply_from_uci: set up the switch from a uci configuration
 * @dev: switch device struct
 * @p: uci package which contains the desired global config
 */
int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p);

#endif