001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 *
020 */
021
022 package org.apache.qpid.server.security.access.plugins;
023
024 import org.apache.commons.configuration.Configuration;
025 import org.apache.log4j.Logger;
026 import org.apache.qpid.AMQConnectionException;
027 import org.apache.qpid.framing.AMQMethodBody;
028 import org.apache.qpid.framing.AMQShortString;
029 import org.apache.qpid.framing.BasicConsumeBody;
030 import org.apache.qpid.framing.BasicPublishBody;
031
032 import org.apache.qpid.protocol.AMQConstant;
033 import org.apache.qpid.server.exchange.Exchange;
034 import org.apache.qpid.server.protocol.AMQProtocolSession;
035 import org.apache.qpid.server.queue.AMQQueue;
036 import org.apache.qpid.server.security.access.ACLManager;
037 import org.apache.qpid.server.security.access.ACLPlugin;
038 import org.apache.qpid.server.security.access.ACLPluginFactory;
039 import org.apache.qpid.server.security.access.AccessResult;
040 import org.apache.qpid.server.security.access.Permission;
041 import org.apache.qpid.server.security.access.PrincipalPermissions;
042 import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult;
043 import org.apache.qpid.server.virtualhost.VirtualHost;
044
045 import java.util.Map;
046 import java.util.concurrent.ConcurrentHashMap;
047
048 /**
049 * This uses the default
050 */
051 public class SimpleXML implements ACLPlugin
052 {
053 public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
054 {
055 public boolean supportsTag(String name)
056 {
057 return name.startsWith("access_control_list");
058 }
059
060 public ACLPlugin newInstance(Configuration config)
061 {
062 SimpleXML plugin = new SimpleXML();
063 plugin.setConfiguration(config);
064 return plugin;
065 }
066 };
067
068 private Map<String, PrincipalPermissions> _users;
069 private final AccessResult GRANTED = new AccessResult(this, AccessResult.AccessStatus.GRANTED);
070
071 public SimpleXML()
072 {
073 _users = new ConcurrentHashMap<String, PrincipalPermissions>();
074 }
075
076 public void setConfiguration(Configuration config)
077 {
078 processConfig(config);
079 }
080
081 private void processConfig(Configuration config)
082 {
083 processPublish(config);
084
085 processConsume(config);
086
087 processCreate(config);
088 }
089
090 /**
091 * Publish format takes Exchange + Routing Key Pairs
092 *
093 * @param config
094 * XML Configuration
095 */
096 private void processPublish(Configuration config)
097 {
098 Configuration publishConfig = config.subset("access_control_list.publish");
099
100 // Process users that have full publish permission
101 String[] users = publishConfig.getStringArray("users.user");
102
103 for (String user : users)
104 {
105 grant(Permission.PUBLISH, user);
106 }
107
108 // Process exchange limited users
109 int exchangeCount = 0;
110 Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
111
112 while (!exchangeConfig.isEmpty())
113 {
114 // Get Exchange Name
115 AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name"));
116
117 // Get Routing Keys
118 int keyCount = 0;
119 Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
120
121 while (!routingkeyConfig.isEmpty())
122 {
123 // Get RoutingKey Value
124 AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value"));
125
126 // Apply Exchange + RoutingKey permissions to Users
127 users = routingkeyConfig.getStringArray("users.user");
128 for (String user : users)
129 {
130 grant(Permission.PUBLISH, user, exchangeName, routingKeyValue);
131 }
132
133 // Apply permissions to Groups
134
135 // Check for more configs
136 keyCount++;
137 routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
138 }
139
140 // Apply Exchange wide permissions to Users
141 users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user");
142
143 for (String user : users)
144 {
145 grant(Permission.PUBLISH, user, exchangeName);
146 }
147
148 // Apply permissions to Groups
149 exchangeCount++;
150 exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
151 }
152 }
153
154 private void grant(Permission permission, String user, Object... parameters)
155 {
156 PrincipalPermissions permissions = _users.get(user);
157
158 if (permissions == null)
159 {
160 permissions = new PrincipalPermissions(user);
161 }
162
163 _users.put(user, permissions);
164 permissions.grant(permission, parameters);
165 }
166
167 private void processConsume(Configuration config)
168 {
169 Configuration consumeConfig = config.subset("access_control_list.consume");
170
171 // Process queue limited users
172 int queueCount = 0;
173 Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
174
175 while (!queueConfig.isEmpty())
176 {
177 // Get queue Name
178 AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
179 // if there is no name then there may be a temporary element
180 boolean temporary = queueConfig.containsKey("temporary");
181 boolean ownQueues = queueConfig.containsKey("own_queues");
182
183 // Process permissions for this queue
184 String[] users = queueConfig.getStringArray("users.user");
185 for (String user : users)
186 {
187 grant(Permission.CONSUME, user, queueName, temporary, ownQueues);
188 }
189
190 // See if we have another config
191 queueCount++;
192 queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
193 }
194
195 // Process users that have full consume permission
196 String[] users = consumeConfig.getStringArray("users.user");
197
198 for (String user : users)
199 {
200 grant(Permission.CONSUME, user);
201 }
202 }
203
204 private void processCreate(Configuration config)
205 {
206 Configuration createConfig = config.subset("access_control_list.create");
207
208 // Process create permissions for queue creation
209 int queueCount = 0;
210 Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
211
212 while (!queueConfig.isEmpty())
213 {
214 // Get queue Name
215 AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
216
217 // if there is no name then there may be a temporary element
218 boolean temporary = queueConfig.containsKey("temporary");
219
220 int exchangeCount = 0;
221 Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
222
223 while (!exchangeConfig.isEmpty())
224 {
225
226 AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
227 AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key"));
228
229 // Process permissions for this queue
230 String[] users = exchangeConfig.getStringArray("users.user");
231 for (String user : users)
232 {
233 grant(Permission.CREATEEXCHANGE, user, exchange);
234 grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange
235 .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey));
236 }
237
238 // See if we have another config
239 exchangeCount++;
240 exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
241 }
242
243 // Process users that are not bound to an exchange
244 String[] users = queueConfig.getStringArray("users.user");
245
246 for (String user : users)
247 {
248 grant(Permission.CREATEQUEUE, user, temporary, queueName);
249 }
250
251 // See if we have another config
252 queueCount++;
253 queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
254 }
255
256 // Process create permissions for exchange creation
257 int exchangeCount = 0;
258 Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")");
259
260 while (!exchangeConfig.isEmpty())
261 {
262 AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
263 AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class"));
264
265 // Process permissions for this queue
266 String[] users = exchangeConfig.getStringArray("users.user");
267 for (String user : users)
268 {
269 grant(Permission.CREATEEXCHANGE, user, exchange, clazz);
270 }
271
272 // See if we have another config
273 exchangeCount++;
274 exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
275 }
276
277 // Process users that have full create permission
278 String[] users = createConfig.getStringArray("users.user");
279
280 for (String user : users)
281 {
282 grant(Permission.CREATEEXCHANGE, user);
283 grant(Permission.CREATEQUEUE, user);
284 }
285
286 }
287
288 public String getPluginName()
289 {
290 return "Simple";
291 }
292
293 public AuthzResult authoriseBind(AMQProtocolSession session, Exchange exch, AMQQueue queue, AMQShortString routingKey)
294 {
295 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
296 if (principalPermissions == null)
297 {
298 return AuthzResult.DENIED;
299 }
300 else
301 {
302 return principalPermissions.authorise(Permission.BIND, null, exch, queue, routingKey);
303 }
304 }
305
306 public AuthzResult authoriseConnect(AMQProtocolSession session, VirtualHost virtualHost)
307 {
308 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
309 if (principalPermissions == null)
310 {
311 return AuthzResult.DENIED;
312 }
313 else
314 {
315 return principalPermissions.authorise(Permission.ACCESS);
316 }
317 }
318
319 public AuthzResult authoriseConsume(AMQProtocolSession session, boolean noAck, AMQQueue queue)
320 {
321 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
322 if (principalPermissions == null)
323 {
324 return AuthzResult.DENIED;
325 }
326 else
327 {
328 return principalPermissions.authorise(Permission.CONSUME, queue);
329 }
330 }
331
332 public AuthzResult authoriseConsume(AMQProtocolSession session, boolean exclusive, boolean noAck, boolean noLocal,
333 boolean nowait, AMQQueue queue)
334 {
335 return authoriseConsume(session, noAck, queue);
336 }
337
338 public AuthzResult authoriseCreateExchange(AMQProtocolSession session, boolean autoDelete, boolean durable,
339 AMQShortString exchangeName, boolean internal, boolean nowait, boolean passive, AMQShortString exchangeType)
340 {
341 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
342 if (principalPermissions == null)
343 {
344 return AuthzResult.DENIED;
345 }
346 else
347 {
348 return principalPermissions.authorise(Permission.CREATEEXCHANGE, exchangeName);
349 }
350 }
351
352 public AuthzResult authoriseCreateQueue(AMQProtocolSession session, boolean autoDelete, boolean durable, boolean exclusive,
353 boolean nowait, boolean passive, AMQShortString queue)
354 {
355 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
356 if (principalPermissions == null)
357 {
358 return AuthzResult.DENIED;
359 }
360 else
361 {
362 return principalPermissions.authorise(Permission.CREATEQUEUE, autoDelete, queue);
363 }
364 }
365
366 public AuthzResult authoriseDelete(AMQProtocolSession session, AMQQueue queue)
367 {
368 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
369 if (principalPermissions == null)
370 {
371 return AuthzResult.DENIED;
372 }
373 else
374 {
375 return principalPermissions.authorise(Permission.DELETE);
376 }
377 }
378
379 public AuthzResult authoriseDelete(AMQProtocolSession session, Exchange exchange)
380 {
381 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
382 if (principalPermissions == null)
383 {
384 return AuthzResult.DENIED;
385 }
386 else
387 {
388 return principalPermissions.authorise(Permission.DELETE);
389 }
390 }
391
392 public AuthzResult authorisePublish(AMQProtocolSession session, boolean immediate, boolean mandatory,
393 AMQShortString routingKey, Exchange e)
394 {
395 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
396 if (principalPermissions == null)
397 {
398 return AuthzResult.DENIED;
399 }
400 else
401 {
402 return principalPermissions.authorise(Permission.PUBLISH, e, routingKey);
403 }
404 }
405
406 public AuthzResult authorisePurge(AMQProtocolSession session, AMQQueue queue)
407 {
408 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
409 if (principalPermissions == null)
410 {
411 return AuthzResult.DENIED;
412 }
413 else
414 {
415 return principalPermissions.authorise(Permission.PURGE);
416 }
417 }
418
419 public AuthzResult authoriseUnbind(AMQProtocolSession session, Exchange exch, AMQShortString routingKey, AMQQueue queue)
420 {
421 PrincipalPermissions principalPermissions = _users.get(session.getAuthorizedID().getName());
422 if (principalPermissions == null)
423 {
424 return AuthzResult.DENIED;
425 }
426 else
427 {
428 return principalPermissions.authorise(Permission.UNBIND);
429 }
430 }
431
432 }
|