Пример #1
0
int
deregister_domain(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
	isns_simple_t	*msg;
	uint32_t	dd_id, status;

	if (!parse_dd_deregistration(argv, argc, &dd_id, &attrs))
		isns_fatal("Unable to parse DD registration\n");

	msg = isns_create_dd_deregistration(clnt, dd_id, &attrs);
	isns_attr_list_destroy(&attrs);

	if (msg == NULL) {
		isns_error("Cannot create message\n");
		return ISNS_INTERNAL_ERROR;
	}

	status = isns_client_call(clnt, &msg);
	if (status != ISNS_SUCCESS) {
		isns_error("Deregistration failed: %s\n",
				isns_strerror(status));
		return status;
	}

	isns_simple_free(msg);
	return status;
}
Пример #2
0
/*
 * Load a DSA key from the cert store
 * In fact, this will load RSA keys as well.
 */
static EVP_PKEY *
__isns_simple_keystore_find(isns_keystore_t *store_base,
		const char *name, size_t namelen)
{
	isns_simple_keystore_t *store = (isns_simple_keystore_t *) store_base;
	char		*pathname;
	size_t		capacity;
	EVP_PKEY	*result;

	/* Refuse to open key files with names
	 * that refer to parent directories */
	if (memchr(name, '/', namelen) || name[0] == '.')
		return NULL;

	capacity = strlen(store->sc_dirpath) + 2 + namelen;
	pathname = isns_malloc(capacity);
	if (!pathname)
		isns_fatal("Out of memory.");
	snprintf(pathname, capacity,
			"%s/%.*s", store->sc_dirpath,
			(int) namelen, name);
	if (access(pathname, R_OK) < 0) {
		isns_free(pathname);
		return NULL;
	}
	result = isns_dsasig_load_public_pem(NULL, pathname);
	isns_free(pathname);
	return result;
}
Пример #3
0
int
query_entity_id(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	uint32_t	status;
	isns_simple_t	*qry;
	const char	*eid;

	if (argc == 1 && !strcmp(argv[0], "help")) {
		printf("Query iSNS for own entity ID.\n"
		       "No arguments allowed\n");
		exit(0);
	}
	if (argc != 0)
		isns_fatal("EID query - no arguments accepted\n");

	isns_attr_list_append_string(&query_key,
			ISNS_TAG_ISCSI_NAME,
			isns_config.ic_source_name);
	qry = isns_create_query(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	isns_query_request_attr_tag(qry, ISNS_TAG_ENTITY_IDENTIFIER);

	status = isns_client_call(clnt, &qry);
	if (status != ISNS_SUCCESS) {
		isns_error("Query failed: %s\n", isns_strerror(status));
		return status;
	}

	status = isns_query_response_get_objects(qry, &objects);
	if (status) {
		isns_error("Unable to extract object list from query response: %s\n",
				isns_strerror(status), status);
		return status;
	}

	status = ISNS_NO_SUCH_ENTRY;
	if (objects.iol_count == 0) {
		isns_error("Node %s not registered with iSNS\n",
				isns_config.ic_source_name);
	} else
	if (!isns_object_get_string(objects.iol_data[0],
				ISNS_TAG_ENTITY_IDENTIFIER, &eid)) {
		isns_error("Query for %s returned an object without EID\n",
				isns_config.ic_source_name);
	} else {
		printf("%s\n", eid);
		status = ISNS_SUCCESS;
	}

	isns_object_list_destroy(&objects);
	isns_simple_free(qry);

	return status;
}
Пример #4
0
isns_attr_t *
generate_key_callback(void)
{
	EVP_PKEY	*pkey;

	if (opt_keyfile == NULL)
		isns_fatal("Key generation requires --keyfile option\n");

	if (!(pkey = isns_dsa_generate_key()))
		isns_fatal("Key generation failed\n");

	if (!isns_dsa_store_private(opt_keyfile, pkey))
		isns_fatal("Unable to write private key to %s\n",
				opt_keyfile);

	printf("Stored DSA private key in %s\n", opt_keyfile);
	return __key_to_attr(pkey);
}
Пример #5
0
isns_attr_t *
load_key_callback(const char *pathname)
{
	EVP_PKEY	*pkey;

	if (!(pkey = isns_dsa_load_public(pathname)))
		isns_fatal("Unable to load public key from file %s\n", pathname);

	return __key_to_attr(pkey);
}
Пример #6
0
static int
__create_policy(isns_client_t *clnt, const isns_attr_list_t *attrs)
{
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	isns_object_t	*obj;
	int		status;

	obj = isns_create_object(&isns_policy_template, attrs, NULL);
	if (!obj)
		isns_fatal("Cannot create policy object\n");
	isns_object_list_append(&objects, obj);

	status = __register_objects(clnt, NULL, &objects);
	isns_object_list_destroy(&objects);
	return status;
}
Пример #7
0
/*
 * Create a new policy
 */
int
edit_policy(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
	int		status;

	if (!parse_policy(argc, argv, &attrs,
				"Edit an existing policy",
				"--edit-policy"))
		isns_fatal("Cannot parse policy\n");

	status = __create_policy(clnt, &attrs);
	isns_attr_list_destroy(&attrs);

	return status;
}
Пример #8
0
int
list_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t	query_keys = ISNS_ATTR_LIST_INIT;
	isns_object_template_t	*query_type = NULL;
	isns_simple_t		*simp;
	int			status, count = 0;

	if (!parse_list(argc, argv, &query_type, &query_keys))
		isns_fatal("Unable to parse parameters\n");

	simp = isns_create_getnext(clnt, query_type, &query_keys);
	while (1) {
		isns_object_t	*obj = NULL;
		isns_simple_t	*followup;

		status = isns_client_call(clnt, &simp);
		if (status)
			break;

		status = isns_getnext_response_get_object(simp, &obj);
		if (status)
			break;

		printf("Object %u:\n", count++);
		isns_object_print(obj, isns_print_stdout);
		isns_object_release(obj);

		followup = isns_create_getnext_followup(clnt,
				simp, &query_keys);
		isns_simple_free(simp);
		simp = followup;
	}

	if (status == ISNS_SOURCE_UNAUTHORIZED
	 && query_type == &isns_policy_template
	 && !opt_local)
		isns_warning("Please use --local trying to list policies\n");

	if (status != ISNS_NO_SUCH_ENTRY) {
		isns_error("GetNext call failed: %s\n",
				isns_strerror(status));
		return status;
	}
	return ISNS_SUCCESS;
}
Пример #9
0
int
register_objects(isns_client_t *clnt,
		int argc, char **argv)
{
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	isns_object_t	*key_obj = NULL;
	uint32_t	status;

	if (opt_key != NULL) {
		isns_attr_list_t key_attrs = ISNS_ATTR_LIST_INIT;
		struct isns_attr_list_parser state;

		isns_attr_list_parser_init(&state, NULL);

		if (!isns_parse_attrs(1, &opt_key, &key_attrs, &state)) {
			isns_error("Cannot parse registration key \"%s\"\n",
					opt_key);
			return 0;
		}

		key_obj = isns_create_object(isns_attr_list_parser_context(&state),
				&key_attrs, NULL);
		isns_attr_list_destroy(&key_attrs);

		if (!key_obj) {
			isns_error("Cannot create registration key object\n");
			return 0;
		}
	} else {
		/* If the user does not provide a key object, 
		 * create/update an entity.
		 */
		key_obj = isns_create_entity(ISNS_ENTITY_PROTOCOL_ISCSI, NULL);
	}

	if (!parse_registration(argv, argc, &objects, key_obj))
		isns_fatal("Unable to parse registration\n");

	status = __register_objects(clnt, key_obj, &objects);
	isns_object_list_destroy(&objects);

	isns_object_release(key_obj);
	return status;
}
Пример #10
0
/*
 * Enroll a new client
 */
int
enroll_client(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
	const char	*client_name;
	int		status;

	if (argc == 0)
		usage(1, "Missing client name");

	client_name = *argv++; --argc;

	isns_attr_list_append_string(&attrs,
			OPENISNS_TAG_POLICY_SPI,
			client_name);
#if 0
	isns_attr_list_append_string(&attrs,
			OPENISNS_TAG_POLICY_SOURCE_NAME,
			client_name);
#endif

	if (!opt_keyfile) {
		static char 	namebuf[PATH_MAX];

		snprintf(namebuf, sizeof(namebuf), "%s.key", client_name);
		opt_keyfile = namebuf;
	}

	if (argc && !parse_policy(argc, argv, &attrs,
				"Enroll an iSNS client",
				"--enroll hostname"))
		isns_fatal("Cannot parse policy\n");

	/* If no key is given, generate one */
	if (!isns_attr_list_contains(&attrs, OPENISNS_TAG_POLICY_KEY)) {
		printf("No key given, generating one\n");
		isns_attr_list_append_attr(&attrs,
				generate_key_callback());
	}

	status = __create_policy(clnt, &attrs);
	isns_attr_list_destroy(&attrs);
	return status;
}
Пример #11
0
int
query_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_attr_list_t oper_attrs = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	uint32_t	status;
	isns_simple_t	*qry;
	unsigned int	i;

	if (!parse_query(argv, argc, &query_key, &oper_attrs))
		isns_fatal("Unable to parse query\n");

	qry = isns_create_query(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	/* Add the list of attributes we request */
	for (i = 0; i < oper_attrs.ial_count; ++i)
		isns_query_request_attr(qry, oper_attrs.ial_data[i]);
	isns_attr_list_destroy(&oper_attrs);

	status = isns_client_call(clnt, &qry);
	if (status != ISNS_SUCCESS) {
		isns_error("Query failed: %s\n", isns_strerror(status));
		return status;
	}

	status = isns_query_response_get_objects(qry, &objects);
	if (status) {
		isns_error("Unable to extract object list from query response: %s\n",
				isns_strerror(status), status);
		return status;
	}

	isns_object_list_print(&objects, isns_print_stdout);
	isns_object_list_destroy(&objects);
	isns_simple_free(qry);

	return status;
}
Пример #12
0
int
deregister_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	isns_simple_t	*dereg;
	uint32_t	status;

	if (!parse_deregistration(argv, argc, &query_key))
		isns_fatal("Unable to parse unregistration\n");

	dereg = isns_create_deregistration(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	status = isns_client_call(clnt, &dereg);
	if (status != ISNS_SUCCESS) {
		isns_error("Deregistration failed: %s\n",
				isns_strerror(status));
		return status;
	}

#if 0
	status = isns_dereg_msg_response_get_objects(dereg, &objects);
	if (status) {
		isns_error("Unable to extract object list from deregistration response: %s\n",
				isns_strerror(status), status);
		goto done;
	}
	isns_object_list_print(&objects, isns_print_stdout);
#endif

	isns_object_list_destroy(&objects);
	isns_simple_free(dereg);

	return status;
}
Пример #13
0
/*
 * Parse the query string given by the user
 *
 * 5.6.5.2
 * The Message Key may contain key or non-key attributes or no
 * attributes at all.  If multiple attributes are used as the
 * Message Key, then they MUST all be from the same object type
 * (e.g., IP address and TCP/UDP Port are attributes of the
 * Portal object type).
 */
int
parse_query(char **argv, int argc, isns_attr_list_t *keys, isns_attr_list_t *query)
{
	struct isns_attr_list_parser state;

	isns_attr_list_parser_init(&state, NULL);
	state.nil_permitted = 1;

	if (argc == 1 && !strcmp(argv[0], "help")) {
		printf("Object query:\n"
		       " isnsadm --query attr=value attr=value ... ?query-attr ?query-attr ...\n"
		       "All key attributes must refer to a common object type.\n"
		       "Query attributes specify the attributes the server should return,"
		       "and can refer to any object type.\n"
		       "The following attributes are recognized:\n");
		isns_attr_list_parser_help(&state);
		exit(0);
	}

	if (argc == 0)
		isns_fatal("Missing query attributes\n");

	return isns_parse_query_attrs(argc, argv, keys, query, &state);
}
Пример #14
0
int
main(int argc, char **argv)
{
	isns_client_t	*clnt;
	isns_security_t	*security = NULL;
	int		c, status;

	while ((c = getopt_long(argc, argv, "46Cc:d:hK:k:l", options, NULL)) != -1) {
		switch (c) {
		case '4':
			opt_af = AF_INET;
			break;

		case '6':
			opt_af = AF_INET6;
			break;

		case 'C':
			opt_control = 1;
			break;

		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'h':
			usage(0, NULL);
			break;

		case 'K':
			opt_keyfile = optarg;
			break;

		case 'k':
			opt_key = optarg;
			break;

		case 'l':
			opt_local = 1;
			break;

		case 'r':
			opt_replace = 1;
			break;

		case 'V':
			printf("Open-iSNS version %s\n"
			       "Copyright (C) 2007, Olaf Kirch <*****@*****.**>\n",
			       OPENISNS_VERSION_STRING);
			return 0;

		case DO_REGISTER:
		case DO_QUERY:
		case DO_QUERY_EID:
		case DO_LIST:
		case DO_DEREGISTER:
		case DO_DD_REGISTER:
		case DO_DD_DEREGISTER:
		case DO_ENROLL:
		case DO_EDIT_POLICY:
		case DO_DELETE_POLICY:
			if (opt_action)
				usage(1, "You cannot specify more than one mode\n");
			opt_action = c;
			break;

		default:
			usage(1, "Unknown option");
		}
	}
	
	isns_read_config(opt_configfile);

	if (!isns_config.ic_source_name)
		usage(1, "Please specify an iSNS source name");
	if (!isns_config.ic_server_name)
		usage(1, "Please specify an iSNS server name");
	if (!opt_action)
		usage(1, "Please specify an operating mode");

	if (opt_control) {
		if (!isns_config.ic_security)
			isns_fatal("Cannot use control mode, security disabled\n");
		security = isns_control_security_context(0);
		if (!security)
			isns_fatal("Unable to create control security context\n");

		/* Create a networked client, using isns.control as
		 * the source name */
		clnt = isns_create_client(security, isns_config.ic_control_name);
	} else if (opt_local) {
		/* Create a local client, using isns.control as
		 * the source name */
		clnt = isns_create_local_client(security,
				isns_config.ic_control_name);
	} else {
		/* Create a networked client, using the configured
		 * source name */
		clnt = isns_create_default_client(security);
	}

	if (clnt == NULL)
		return 1;

	/* We're an interactive app, and don't want to retry
	 * forever if the server refuses us. */
	isns_socket_set_disconnect_fatal(clnt->ic_socket);

	/* Get the IP address we use to talk to the iSNS server */
	if (opt_myaddr.ss_family == AF_UNSPEC && !opt_local) {
		if (!isns_socket_get_local_addr(clnt->ic_socket, &opt_myaddr))
			isns_fatal("Unable to obtain my IP address\n");
		isns_addr_set_port((struct sockaddr *) &opt_myaddr, 860);
	}

	argv += optind; argc -= optind;
	switch (opt_action) {
	case DO_REGISTER:
		status = register_objects(clnt, argc, argv);
		break;

	case DO_QUERY:
		status = query_objects(clnt, argc, argv);
		break;

	case DO_QUERY_EID:
		status = query_entity_id(clnt, argc, argv);
		break;

	case DO_LIST:
		status = list_objects(clnt, argc, argv);
		break;

	case DO_DEREGISTER:
		status = deregister_objects(clnt, argc, argv);
		break;

	case DO_DD_REGISTER:
		status = register_domain(clnt, argc, argv);
		break;

	case DO_DD_DEREGISTER:
		status = deregister_domain(clnt, argc, argv);
		break;


	case DO_ENROLL:
		status = enroll_client(clnt, argc, argv);
		break;

	case DO_EDIT_POLICY:
		status = edit_policy(clnt, argc, argv);
		break;

	// case DO_DELETE_POLICY:

	default:
		isns_fatal("Not yet implemented\n");
		status = 1; /* compiler food */
	}

	return status != ISNS_SUCCESS;
}
Пример #15
0
int
main(int argc, char **argv)
{
	isns_server_t	*server;
	isns_source_t	*source;
	isns_db_t	*db;
	int		c;

#ifdef MTRACE
	mtrace();
#endif

	while ((c = getopt_long(argc, argv, "46c:d:Efhr:", options, NULL)) != -1) {
		switch (c) {
		case '4':
			opt_af = AF_INET;
			break;

		case '6':
			opt_af = AF_INET6;
			break;

		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'E':
			opt_esi = 0;
			break;

		case 'f':
			opt_foreground = 1;
			break;

		case 'h':
			usage(0, NULL);

		case 'r':
			if (!strcasecmp(optarg, "initiator"))
				opt_role = ROLE_INITIATOR;
			else
			if (!strcasecmp(optarg, "control")
			 || !strcasecmp(optarg, "monitor"))
				opt_role = ROLE_MONITOR;
			else {
				isns_error("Unknown role \"%s\"\n", optarg);
				usage(1, NULL);
			}
			break;

		case 'V':
			printf("Open-iSNS version %s\n"
			       "Copyright (C) 2007, Olaf Kirch <*****@*****.**>\n",
			       OPENISNS_VERSION_STRING);
			return 0;

		default:
			usage(1, "Unknown option");
		}
	}

	if (optind != argc)
		usage(1, NULL);

	/* If the config code derives the source name
	 * automatically, we want it to be distinct from
	 * any other source name (chosen by eg the iSCSI
	 * initiator). Adding a suffix of ":isns" is a
	 * somewhat lame attempt.
	 */
	isns_config.ic_source_suffix = "isns";

	isns_read_config(opt_configfile);

	if (!isns_config.ic_source_name)
		usage(1, "Please specify an iSNS source name");
	source = isns_source_create_iscsi(isns_config.ic_source_name);

	isns_write_pidfile(isns_config.ic_pidfile);

	if (!opt_foreground) {
		if (daemon(0, 0) < 0)
			isns_fatal("Unable to background server process\n");
		isns_log_background();
		isns_update_pidfile(isns_config.ic_pidfile);
	}

	install_sighandler(SIGTERM, sig_cleanup);
	install_sighandler(SIGINT, sig_cleanup);
	install_sighandler(SIGUSR2, sig_reread);

	/* Create a DB object that shadows our portal list. This is for ESI -
	 * when an ESI comes in, the library will look up the portal in this
	 * database, and update its mtime. By checking the mtime at regular
	 * intervals, we can verify whether the server's ESIs actually
	 * reach us.
	 */
	db = isns_db_open_shadow(&local_portals);

	server = isns_create_server(source, db, &isns_callback_service_ops);
	isns_server_set_scn_callback(server, scn_callback);

	run_discovery(server);
	return 0;
}
Пример #16
0
int
parse_registration(char **argv, int argc, isns_object_list_t *objs, isns_object_t *key_obj)
{
	struct sockaddr_storage def_addr;
	isns_object_t	*entity = NULL, *last_portal = NULL, *last_node = NULL;
	const char	*def_port = NULL;
	int		i;

	if (argc == 1 && !strcmp(argv[0], "help")) {
		printf("Object registration:\n"
		       " isnsadm [-key attr=value] --register type,attr=value,... type,attr=value,...\n"
		       "Where type can be one of:\n"
		       "  entity         create/update network entity\n"
		       "  initiator      create iSCSI initiator storage node\n"
		       "  target         create iSCSI target storage node\n"
		       "  control        create control node\n"
		       "  portal         create portal\n"
		       "  pg             create portal group\n"
		       "\nThe following attributes are recognized:\n");

		isns_attr_list_parser_help(NULL);
		exit(0);
	}

	if (argc == 0)
		usage(1, "Missing object list\n");

	if (key_obj) {
		//isns_object_list_append(objs, key_obj);
		if (isns_object_is_entity(key_obj))
			entity = key_obj;
	}

	def_addr = opt_myaddr;

	for (i = 0; i < argc; ++i) {
		isns_attr_list_t attrlist = ISNS_ATTR_LIST_INIT;
		struct isns_attr_list_parser state;
		isns_object_t	*obj;
		char		*type, *name, *value, *next_attr;
		char		*attrs[128];
		unsigned int	nattrs = 0;

		name = argv[i];

		if ((next_attr = strchr(name, ',')) != NULL)
			*next_attr++ = '\0';

		while (next_attr && *next_attr) {
			if (nattrs > 128)
				isns_fatal("Too many attributes\n");

			/* Show mercy with fat fingered
			 * people,,,,who,cannot,,,type,properly */
			if (next_attr[0] != ',')
				attrs[nattrs++] = next_attr;
			if ((next_attr = strchr(next_attr, ',')) != NULL)
				*next_attr++ = '\0';
		}

		if ((value = strchr(name, '=')) != NULL)
			*value++ = '\0';

		type = name;
		if (!strcmp(name, "entity")) {
			if (entity == NULL) {
				isns_error("Cannot create entity object "
					"within this key object\n");
				return 0;
			}

			if (value != NULL)
				isns_object_set_string(entity,
						ISNS_TAG_ENTITY_IDENTIFIER,
						value);
			obj = isns_object_get(entity);
			goto handle_attributes;
		} else
		if (!strcmp(name, "node")
		 || !strcmp(name, "initiator")) {
			const char *node_name;

			node_name = isns_config.ic_source_name;
			if (value)
				node_name = value;

			obj = isns_create_storage_node(node_name,
					ISNS_ISCSI_INITIATOR_MASK,
					entity);
			last_node = obj;

			isns_addr_set_port((struct sockaddr *) &def_addr,
					ISNS_DEFAULT_PORT_INITIATOR);
			def_port = "iscsi";
		} else
		if (!strcmp(name, "target")) {
			const char *node_name;

			node_name = isns_config.ic_source_name;
			if (value)
				node_name = value;
			obj = isns_create_storage_node(node_name,
					ISNS_ISCSI_TARGET_MASK,
					entity);
			last_node = obj;

			isns_addr_set_port((struct sockaddr *) &def_addr,
					ISNS_DEFAULT_PORT_TARGET);
			def_port = "iscsi-target";
		} else
		if (!strcmp(name, "control")) {
			const char *node_name;

			node_name = isns_config.ic_control_name;
			if (value)
				node_name = value;
			obj = isns_create_storage_node(node_name,
					ISNS_ISCSI_CONTROL_MASK,
					entity);
			last_node = obj;

			def_port = NULL;
		} else
		if (!strcmp(name, "portal")) {
			isns_portal_info_t portal_info;

			if (value == NULL) {
				if (def_port == NULL)
					isns_fatal("portal must follow initiator or target\n");
				isns_portal_init(&portal_info,
						(struct sockaddr *) &def_addr,
						IPPROTO_TCP);
			} else
			if (!isns_portal_parse(&portal_info, value, def_port))
				isns_fatal("Unable to parse portal=%s\n", value);
			obj = isns_create_portal(&portal_info, entity);
			last_portal = obj;
		} else
		if (!strcmp(name, "pg")) {
			if (value)
				isns_fatal("Unexpected value for portal group\n");
			if (!last_portal || !last_node)
				isns_fatal("Portal group registration must follow portal and node\n");
			obj = isns_create_portal_group(last_portal, last_node, 10);
		} else {
			isns_error("Unknown object type \"%s\"\n", name);
			return 0;
		}

		if (obj == NULL) {
			isns_error("Failure to create %s object\n", name);
			return 0;
		}
		isns_object_list_append(objs, obj);

handle_attributes:
		isns_attr_list_parser_init(&state, obj->ie_template);
		state.default_port = def_port;

		if (!isns_parse_attrs(nattrs, attrs, &attrlist, &state)
		 || !isns_object_set_attrlist(obj, &attrlist)) {
			isns_error("Failure to set all %s attributes\n", name);
			isns_attr_list_destroy(&attrlist);
			return 0;
		}

		isns_attr_list_destroy(&attrlist);
		isns_object_release(obj);
	}

	return 1;
}
Пример #17
0
isns_attr_t *
load_key_callback(const char *pathname)
{
	isns_fatal("Authentication disabled in this build\n");
	return NULL;
}
Пример #18
0
int
main(int argc, char **argv)
{
	isns_server_t	*server;
	isns_source_t	*source;
	isns_db_t	*db;
	int		c;

#ifdef MTRACE
	mtrace();
#endif

	while ((c = getopt_long(argc, argv, "46c:d:fh", options, NULL)) != -1) {
		switch (c) {
		case '4':
			opt_af = AF_INET;
			break;

		case '6':
			opt_af = AF_INET6;
			break;

		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'f':
			opt_foreground = 1;
			break;

		case MODE_DUMP_DB:
		case MODE_INIT:
			opt_mode = c;
			break;

		case 'h':
			usage(0, NULL);

		case 'V':
			printf("Open-iSNS version %s\n"
			       "Copyright (C) 2007, Olaf Kirch <*****@*****.**>\n",
			       OPENISNS_VERSION_STRING);
			return 0;

		default:
			usage(1, "Unknown option");
		}
	}

	if (optind != argc)
		usage(1, NULL);

	isns_read_config(opt_configfile);

	if (!isns_config.ic_source_name)
		usage(1, "Please specify an iSNS source name");
	source = isns_source_create_iscsi(isns_config.ic_source_name);

	if (opt_mode == MODE_INIT)
		return !init_server();

	if (opt_mode == MODE_NORMAL)
		isns_write_pidfile(isns_config.ic_pidfile);

	db = isns_db_open(isns_config.ic_database);
	if (db == NULL)
		isns_fatal("Unable to open database\n");

	if (opt_mode == MODE_DUMP_DB) {
		isns_db_print(db, isns_print_stdout);
		exit(0);
	}

	if (!opt_foreground) {
		if (daemon(0, 0) < 0)
			isns_fatal("Unable to background server process\n");
		isns_log_background();
		isns_update_pidfile(isns_config.ic_pidfile);
	}

	signal(SIGTERM, cleanup);
	signal(SIGINT, cleanup);

	server = isns_create_server(source, db, &isns_default_service_ops);

	run_server(server, db);
	return 0;
}
Пример #19
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	isns_read_config(opt_configfile);

	isns_assign_string(&isns_config.ic_source_name,
			"iqn.1991-05.com.microsoft:orange");

	clnt = isns_create_default_client(NULL);

	reg = isns_simple_create(ISNS_SCN_DEREGISTER, clnt->ic_source, NULL);

	/* Message attributes */
	attrs = &reg->is_message_attrs;
	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_error("SCNDereg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);


	reg = isns_simple_create(ISNS_DEVICE_DEREGISTER, clnt->ic_source, NULL);

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevDereg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER, clnt->ic_source, NULL);
	reg->is_replace = opt_replace;

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	U32(SCN_PORT,		3230);
	U32(ESI_PORT,		3230);

	U32(PG_TAG,		1);
	STR(PG_ISCSI_NAME,	"iqn.1991-05.com.microsoft:orange");

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	STR(ISCSI_ALIAS,	"<MS SW iSCSI Initiator>");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevAttrReg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	reg = isns_simple_create(ISNS_DEVICE_GET_NEXT, clnt->ic_source, NULL);
	attrs = &reg->is_message_attrs;
	NIL(ISCSI_NAME);

	attrs = &reg->is_operating_attrs;
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_TARGET_MASK);
	NIL(ISCSI_NODE_TYPE);

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevGetNext failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	return 0;
}
Пример #20
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	isns_read_config(opt_configfile);

	isns_assign_string(&isns_config.ic_source_name,
			"iqn.1991-05.com.microsoft:orange");

	clnt = isns_create_default_client(NULL);

	/*
	 * test that we can deregister for SCN events, even though
	 * not registered
	 */
	reg = isns_simple_create(ISNS_SCN_DEREGISTER, clnt->ic_source, NULL);

	/* Message attributes */
	attrs = &reg->is_message_attrs;
	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_error("SCNDereg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully deregistered for SCN events\n");
	isns_simple_free(reg);

	/*
	 * test that we can deregister a device, even though not
	 * registered -- note that the portal group object proceeds
	 * the initiator (name) object in the operating attribute
	 * list
	 */
	reg = isns_simple_create(ISNS_DEVICE_DEREGISTER, clnt->ic_source, NULL);

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevDereg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully deregistered a device\n");
	isns_simple_free(reg);

	/*
	 * test that we can register (w/replace) device attributes
	 */
	reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER,
				 clnt->ic_source, NULL);
	reg->is_replace = opt_replace;

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	U32(SCN_PORT,		3230);
	U32(ESI_PORT,		3230);

	U32(PG_TAG,		1);
	STR(PG_ISCSI_NAME,	"iqn.1991-05.com.microsoft:orange");

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	STR(ISCSI_ALIAS,	"<MS SW iSCSI Initiator>");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevAttrReg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully registered device attributes\n");
	isns_simple_free(reg);

	/*
	 * test that we can call DEVICE GET NEXT to get the next (only)
	 * iscsi Storage Node
	 */
	reg = isns_simple_create(ISNS_DEVICE_GET_NEXT, clnt->ic_source, NULL);
	attrs = &reg->is_message_attrs;
	NIL(ISCSI_NAME);

	attrs = &reg->is_operating_attrs;
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	NIL(ISCSI_NODE_TYPE);

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevGetNext failed: %s\n", isns_strerror(status));
	else
		printf("Successfully got next device node\n");
	isns_simple_free(reg);

	return 0;
}
Пример #21
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c, n, timeout;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	if (optind != argc - 1)
		isns_fatal("Need timeout argument\n");
	timeout = parse_timeout(argv[optind]);

	isns_read_config(opt_configfile);

	/*
	    ---DevAttrReg[REPLACE]---
	    Source:
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	    Message attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	    Operating attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	      0002  uint32      : Entity protocol = iSCSI (2)
	      0010  ipaddr      : Portal IP address = 192.168.1.2
	      0011  uint32      : Portal TCP/UDP port = 33849/tcp
	      0014  uint32      : ESI port = 56288/tcp
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	      0021  uint32      : iSCSI node type = Initiator
	      0022  string      : iSCSI alias = "blue.pauw.homeunix.net"

	      [...]
    	      response status 0x0003 (Invalid registration)

	   This would fail because we got confused about EID in
	   the replace case.
	 */
	isns_assign_string(&isns_config.ic_source_name,
			"iqn.2005-03.org.open-iscsi:blue");

	for (n = 0; n < 2; ++n) {
		clnt = isns_create_default_client(NULL);
		reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER,
				clnt->ic_source, NULL);
		reg->is_replace = opt_replace;

		/* Message attributes */
		attrs = &reg->is_message_attrs;
		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");

		/* Operating attributes */
		attrs = &reg->is_operating_attrs;

		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");
		U32(ENTITY_PROTOCOL,	2);

		isns_portal_parse(&portal_info, "192.168.1.2:33849/tcp", NULL);
		isns_portal_to_attr_list(&portal_info,
				ISNS_TAG_PORTAL_IP_ADDRESS,
				ISNS_TAG_PORTAL_TCP_UDP_PORT,
				attrs);

		U32(ESI_PORT,		56288);
		STR(ISCSI_NAME,		"iqn.2005-03.org.open-iscsi:blue");
		U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
		STR(ISCSI_ALIAS,	"blue.pauw.homeunix.net");
		isns_simple_print(reg, isns_print_stdout);

		status = isns_client_call(clnt, &reg);

		if (status != ISNS_SUCCESS)
			isns_fatal("Unable to register object: %s\n",
					isns_strerror(status));

		printf("Successfully registered object\n");
		// isns_simple_print(reg, isns_print_stdout);
		isns_simple_free(reg);
		isns_client_destroy(clnt);

		if (n == 0) {
			printf("Sleeping for %d seconds\n", timeout);
			sleep(timeout);
		}
	}

	return 0;
}
Пример #22
0
	/* Must pad key. This means we may end up encoding a few
	 * bytes of trash. Oh well. */
	key.len = ISNS_PAD(key.len);

	value = ISNS_VALUE_INIT(opaque, key);
	attr = isns_attr_alloc(OPENISNS_TAG_POLICY_KEY, NULL, &value);

	isns_free(key.ptr);

out:
	EVP_PKEY_free(pkey);
	return attr;
}

isns_attr_t *
generate_key_callback(void)
{
	EVP_PKEY	*pkey;

	if (opt_keyfile == NULL)
		isns_fatal("Key generation requires --keyfile option\n");

	if (!(pkey = isns_dsa_generate_key()))
		isns_fatal("Key generation failed\n");

	if (!isns_dsa_store_private(opt_keyfile, pkey))
		isns_fatal("Unable to write private key to %s\n",
				opt_keyfile);

	printf("Stored DSA private key in %s\n", opt_keyfile);
	return __key_to_attr(pkey);
}

isns_attr_t *
load_key_callback(const char *pathname)
{
	EVP_PKEY	*pkey;

	if (!(pkey = isns_dsa_load_public(pathname)))
		isns_fatal("Unable to load public key from file %s\n", pathname);

	return __key_to_attr(pkey);
}

#else /* WITH_SECURITY */
isns_attr_t *
generate_key_callback(void)
{
	isns_fatal("Authentication disabled in this build\n");
	return NULL;
}
Пример #23
0
/*
 * Server main loop
 */
void
run_server(isns_server_t *server, isns_db_t *db)
{
	isns_socket_t	*sock;
	isns_security_t	*ctx = NULL;
	isns_message_t	*msg, *resp;
	int status;

	if (isns_config.ic_security) {
		const char	*ksname;
		isns_keystore_t	*ks;

		ctx = isns_default_security_context(1);
		if (!(ksname = isns_config.ic_client_keystore))
			isns_fatal("config problem: no key store specified\n");
		if (!strcasecmp(ksname, "db:"))
			ks = isns_create_db_keystore(db);
		else
			ks = isns_create_keystore(ksname);
		if (ks == NULL)
			isns_fatal("Unable to create keystore %s\n", ksname);
		isns_security_set_keystore(ctx, ks);
	}

	status = isns_dd_load_all(db);
	if (status != ISNS_SUCCESS)
		isns_fatal("Problem loading Discovery Domains from database\n");

	if (isns_config.ic_control_socket) {
		sock = isns_create_server_socket(isns_config.ic_control_socket,
				NULL, AF_UNSPEC, SOCK_STREAM);
		if (sock == NULL)
			isns_fatal("Unable to create control socket\n");
		/*
		isns_socket_set_security_ctx(sock, ctx);
		   */
	}

	sock = isns_create_server_socket(isns_config.ic_bind_address,
			"isns", opt_af, SOCK_STREAM);
	if (sock == NULL)
		isns_fatal("Unable to create server socket\n");
	isns_socket_set_security_ctx(sock, ctx);

	if (isns_config.ic_slp_register) {
		slp_url = isns_slp_build_url(0);
		isns_slp_register(slp_url);

		atexit(slp_cleanup);
	}

	isns_esi_init(server);
	isns_scn_init(server);

	while (1) {
		struct timeval timeout = { 0, 0 };
		time_t	now, then, next_timeout = time(NULL) + 3600;

		/* Expire entities that haven't seen any activity
		 * for a while. */
		if (isns_config.ic_registration_period) {
			then = isns_db_expire(db);
			if (then && then < next_timeout)
				next_timeout = then;
		}

		/* Run any timers (eg for ESI) */
		then = isns_run_timers();
		if (then && then < next_timeout)
			next_timeout = then;

		/* There may be pending SCNs, push them out now */
		then = isns_scn_transmit_all();
		if (then && then < next_timeout)
			next_timeout = then;

		/* Purge any objects that have been marked for removal
		 * from the DB (deleting them, or moving them to limbo
		 * state). */
		isns_db_purge(db);

		/* Determine how long we can sleep before working
		 * the ESI queues and DB expiry again. */
		now = time(NULL);
		if (next_timeout <= now)
			continue;
		timeout.tv_sec = next_timeout - now;

		if ((msg = isns_recv_message(&timeout)) == NULL)
			continue;

		if ((resp = isns_process_message(server, msg)) != NULL) {
			isns_socket_t *sock = isns_message_socket(msg);

			isns_socket_send(sock, resp);
			isns_message_release(resp);
		}

		isns_message_release(msg);
	}
}