-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generate_permissions verb + update policy definition to support s…
…ervices and actions (#71) * Add generate permissions security command line Generate an sros2 yaml permissions file with the permissions of every visible node on the dds network. Add custom service security to sros2 Example: run the minimal_publisher_lambda node Execute: `ros2 security generate_permissions node_policies.yaml` It will create the following file in the current directory: ``` /minimal_publisher: services: /minimal_publisher/describe_parameters: allows: - request - reply . . . topics: /parameter_events: allows: - publish - subscribe /topic: allows: - publish ``` cr https://code.amazon.com/reviews/CR-3943967 * Proposed policy definition changes Issue: services and actions are not considered in the policy yaml definition. Solution: Add ipc types (services and actions) Issue: access values are strings with p, s, or ps in order. This is not descriptive and difficult to scale should more permissions become necessary. Solution: Either change the parsing of the string or change the yaml to be more flexible and descriptive for users. The proposed changes include: * Access value is a list, not a string * Add ipc types such as actions and services * Access values are no longer shorthand p or s, but publish/subscribe Amend policy definition with verbose ROS ipc types
- Loading branch information
Showing
5 changed files
with
245 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
## Values used in policy generation | ||
**ipc_types**: The type of ROS IPC in use, such as service, action, or topic | ||
## Definitions | ||
|
||
| name | description | | ||
| ---- | ----------- | | ||
| access permission | The access permission of that node for the specified icp | | ||
| ipc | Inter-process communication, how messages get from one node to another | | ||
| ipc identifier | The specific subsystem id to provide access to (topic name, service name...) | | ||
| ipc types | The inter-process communication subsystem (topics, services...) | | ||
|
||
## Options | ||
Most ipc permissions are given on a client/source basis. | ||
Parameter permissions are slightly different. These specify whether this node is allowed to read/write to another node. | ||
|
||
| ipc type | identifier | access permission options | | ||
| -------- | ---------- | ------------------------- | | ||
| topics | topic name | subscribe, publish | | ||
| services | service name | request, reply | | ||
| actions | action name | call, execute | | ||
| parameters | node name | read, write | | ||
|
||
## Policy yaml file layout | ||
|
||
``` | ||
nodes: | ||
<node_name>: | ||
<ipc_type>: | ||
<ipc_identifier> | ||
access: | ||
-<access_permissions> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,36 @@ | ||
nodes: | ||
listener: | ||
topics: | ||
chatter: | ||
allow: s # can subscribe to chatter | ||
/chatter: | ||
allow: | ||
- subscribe # can subscribe to chatter | ||
talker: | ||
topics: | ||
chatter: | ||
allow: p # can publish on chatter | ||
/chatter: | ||
allow: | ||
- publish # can publish on chatter | ||
listener_py: | ||
topics: | ||
#'*': | ||
# allow: s # this would allow the listener to subscribe to all topics | ||
chatter: | ||
allow: s # can subscribe to chatter | ||
chatter2: | ||
allow: s # can subscribe to chatter2 | ||
# allow: | ||
# - subscribe # this would allow the listener to subscribe to all topics | ||
/chatter: | ||
allow: | ||
- subscribe # can subscribe to chatter | ||
/chatter2: | ||
allow: | ||
- subscribe# can subscribe to chatter2 | ||
talker_py: | ||
topics: | ||
#'*': | ||
# allow: p # this would allow the talker to publish on all topics | ||
chatter: | ||
allow: p # allow publishing on chatter | ||
chatter2: | ||
allow: p # allow publishing on chatter2 | ||
chatter3: | ||
allow: p # allow publishing on chatter3 | ||
# allow: | ||
# - publish # this would allow the talker to publish on all topics | ||
/chatter: | ||
allow: | ||
-publish # allow publishing on chatter | ||
/chatter2: | ||
allow: | ||
- publish# allow publishing on chatter2 | ||
/chatter3: | ||
allow: | ||
-publish # allow publishing on chatter3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Copyright 2016-2017 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
try: | ||
from argcomplete.completers import DirectoriesCompleter | ||
except ImportError: | ||
def DirectoriesCompleter(): | ||
return None | ||
try: | ||
from argcomplete.completers import FilesCompleter | ||
except ImportError: | ||
def FilesCompleter(*, allowednames, directories): | ||
return None | ||
|
||
from collections import defaultdict | ||
|
||
from ros2cli.node.direct import DirectNode | ||
from ros2cli.node.strategy import NodeStrategy | ||
from sros2.api import get_node_names | ||
from sros2.api import get_publisher_info | ||
from sros2.api import get_service_info | ||
from sros2.api import get_subscriber_info | ||
from sros2.verb import VerbExtension | ||
|
||
|
||
def formatTopics(topic_list, permission, topic_map): | ||
for topic in topic_list: | ||
topic_map[topic.name].append(permission) | ||
|
||
|
||
class GeneratePermissionsVerb(VerbExtension): | ||
"""Generate permissions.""" | ||
|
||
def add_arguments(self, parser, cli_name): | ||
|
||
arg = parser.add_argument( | ||
'POLICY_FILE_PATH', help='path of the permission yaml file') | ||
arg.completer = FilesCompleter( | ||
allowednames=('yaml'), directories=False) | ||
|
||
def main(self, *, args): | ||
node_names = [] | ||
with NodeStrategy(args) as node: | ||
node_names = get_node_names(node=node, include_hidden_nodes=False) | ||
policy_dict = {} | ||
with DirectNode(args) as node: | ||
for node_name in node_names: | ||
subscribers = get_subscriber_info(node=node, node_name=node_name) | ||
publishers = get_publisher_info(node=node, node_name=node_name) | ||
services = get_service_info(node=node, node_name=node_name) | ||
topic_map = defaultdict(list) | ||
formatTopics(publishers, 'publish', topic_map) | ||
formatTopics(subscribers, 'subscribe', topic_map) | ||
formatted_topic_map = {} | ||
for topic_name, permission_list in topic_map.items(): | ||
formatted_topic_map[topic_name] = {'allow': permission_list} | ||
service_map = defaultdict(list) | ||
formatTopics(services, 'reply', service_map) | ||
formatted_services_map = {} | ||
for service, permission_list in service_map.items(): | ||
formatted_services_map[service] = {'allow': permission_list} | ||
policy_dict[node_name.name] = {'topics': formatted_topic_map} | ||
policy_dict[node_name.name]['services'] = formatted_services_map | ||
import yaml | ||
from io import open | ||
formatted_policy_dict = {'nodes': policy_dict} | ||
if policy_dict: | ||
with open(args.POLICY_FILE_PATH, 'w') as stream: | ||
yaml.dump(formatted_policy_dict, stream, default_flow_style=False) | ||
else: | ||
print('No nodes found to generate policies') |