Source code: org/activemq/security/jassjacc/PropertiesConfigLoader.java
1 /**
2 *
3 * Copyright 2004 Hiram Chirino
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.activemq.security.jassjacc;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 import org.activemq.message.ActiveMQQueue;
33 import org.activemq.message.ActiveMQTopic;
34
35 /**
36 * Parses a Properties object into a set of {@see org.activemq.security.jassjacc.BrokerSecurityConfig} and
37 * {@see org.activemq.security.jassjacc.DestinationSecurityConfig} objects that can be used to
38 * secure the ActiveMQ broker.
39 *
40 * Sample properties configuration:
41 * <pre>
42 *
43 * # Secure a connection the the 'localhost' broker
44 * connect.roles=admins,traders,brokers,guests
45 *
46 * # Secure the TEST_TOPIC topic.
47 * topic.T1.names=TEST_TOPIC
48 * topic.T1.consume.roles=traders
49 * topic.T1.produce.roles=traders,brokers
50 * topic.T1.send.roles=traders,brokers
51 *
52 * # You can also secure more than one destination in one go.
53 * queue.Q1.names=TEST_QUEUE,A_QUEUE,B_QUEUE
54 * queue.Q1.consume.roles=traders
55 * queue.Q1.produce.roles=traders,brokers
56 * queue.Q1.send.roles=traders,brokers
57 *
58 * </pre>
59 *
60 *
61 * @version $Revision: 1.1.1.1 $
62 */
63 public class PropertiesConfigLoader {
64
65 HashMap destinationMap = new HashMap();
66 BrokerSecurityConfig brokerSecurityConfig = new BrokerSecurityConfig();
67
68 public PropertiesConfigLoader(String brokerName, Properties props) throws IOException {
69
70 brokerSecurityConfig.setBrokerName(brokerName);
71 Pattern brokerConnectRoles = Pattern.compile("^connect\\.roles$");
72 Pattern destNames = Pattern.compile("^(queue|topic)\\.([^\\.]+)\\.names$");
73 Pattern destConsumeRoles = Pattern.compile("^(queue|topic)\\.([^\\.]+)\\.consume\\.roles$");
74 Pattern destProduceRoles = Pattern.compile("^(queue|topic)\\.([^\\.]+)\\.produce\\.roles$");
75 Pattern destSendRoles = Pattern.compile("^(queue|topic)\\.([^\\.]+)\\.send\\.roles$");
76
77 Matcher matcher;
78 Enumeration enumeration;
79
80 enumeration = props.propertyNames();
81 while (enumeration.hasMoreElements()) {
82 String prop = (String) enumeration.nextElement();
83 if ((matcher=brokerConnectRoles.matcher(prop)).matches()) {
84 String[] roles = trim(props.getProperty(prop).split("\\,"));
85 brokerSecurityConfig.setConnectRoles(new HashSet(Arrays.asList(roles)));
86 } else if ((matcher=destNames.matcher(prop)).matches()) {
87 String type = matcher.group(1);
88 String dest = matcher.group(2);
89 setDestNames( type, dest, trim(props.getProperty(prop).split("\\,")) );
90 }
91 }
92
93 enumeration = props.propertyNames();
94 while (enumeration.hasMoreElements()) {
95 String prop = (String) enumeration.nextElement();
96 if ((matcher=destConsumeRoles.matcher(prop)).matches()) {
97 String type = matcher.group(1);
98 String dest = matcher.group(2);
99 setDestConsumeRoles( type, dest, trim(props.getProperty(prop).split("\\,")) );
100 } else if ((matcher=destProduceRoles.matcher(prop)).matches()) {
101 String type = matcher.group(1);
102 String dest = matcher.group(2);
103 setDestProduceRoles( type, dest, trim(props.getProperty(prop).split("\\,")) );
104 } else if ((matcher=destSendRoles.matcher(prop)).matches()) {
105 String type = matcher.group(1);
106 String dest = matcher.group(2);
107 setDestSendRoles( type, dest, trim(props.getProperty(prop).split("\\,")) );
108 }
109 }
110
111 }
112
113 private void setDestSendRoles(String type, String dest, String[] roles) throws IOException {
114 List configs = getDestConfig(type, dest);
115 for (Iterator iter = configs.iterator(); iter.hasNext();) {
116 DestinationSecurityConfig config = (DestinationSecurityConfig) iter.next();
117 config.setProduceRoles(new HashSet(Arrays.asList(roles)));
118 }
119 }
120
121 private void setDestProduceRoles(String type, String dest, String[] roles) throws IOException {
122 List configs = getDestConfig(type, dest);
123 for (Iterator iter = configs.iterator(); iter.hasNext();) {
124 DestinationSecurityConfig config = (DestinationSecurityConfig) iter.next();
125 config.setProduceRoles(new HashSet(Arrays.asList(roles)));
126 }
127 }
128
129 private void setDestConsumeRoles(String type, String dest, String[] roles) throws IOException {
130 List configs = getDestConfig(type, dest);
131 for (Iterator iter = configs.iterator(); iter.hasNext();) {
132 DestinationSecurityConfig config = (DestinationSecurityConfig) iter.next();
133 config.setConsumeRoles(new HashSet(Arrays.asList(roles)));
134 }
135 }
136
137 private List getDestConfig(String type, String dest) throws IOException {
138 List rc = (List) destinationMap.get(type+":"+dest);
139 if( rc==null ) {
140 throw new IOException("Expected property not found: "+type+"."+dest+".names");
141 }
142 return rc;
143 }
144
145 private void setDestNames(String type, String dest, String[] names) throws IOException {
146 ArrayList list = new ArrayList();
147 for (int i = 0; i < names.length; i++) {
148 DestinationSecurityConfig config = new DestinationSecurityConfig();
149 config.setBrokerName( brokerSecurityConfig.getBrokerName() );
150 if( "queue".equals(type) ) {
151 config.setDestination(new ActiveMQQueue(dest));
152 } else {
153 config.setDestination(new ActiveMQTopic(dest));
154 }
155 list.add(config);
156 }
157 destinationMap.put(type+":"+dest, list);
158 }
159
160 private static String[] trim(String[] brokers) {
161 for (int i = 0; i < brokers.length; i++) {
162 brokers[i] = brokers[i].trim();
163 }
164 return brokers;
165 }
166
167 public DestinationSecurityConfig[] getDestinationSecurityConfigs() {
168 ArrayList answer = new ArrayList();
169 for (Iterator iter = destinationMap.values().iterator(); iter.hasNext();) {
170 List l = (List) iter.next();
171 answer.addAll(l);
172 }
173
174 DestinationSecurityConfig rc[] = new DestinationSecurityConfig[answer.size()];
175 answer.toArray(rc);
176 return rc;
177 }
178
179 public BrokerSecurityConfig getBrokerSecurityConfig() {
180 return brokerSecurityConfig;
181 }
182
183 public void installSecurity() {
184 JassJaccSecurityAdapter.secure(brokerSecurityConfig);
185
186 DestinationSecurityConfig[] destinationSecurityConfigs = getDestinationSecurityConfigs();
187 for (int i = 0; i < destinationSecurityConfigs.length; i++) {
188 DestinationSecurityConfig config = destinationSecurityConfigs[i];
189 JassJaccSecurityAdapter.secure(config);
190 }
191
192 }
193
194 }