You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2012/02/21 14:37:42 UTC

svn commit: r1291776 - in /activemq/activemq-apollo/trunk: apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/ apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ apollo-openwire/src/main/scala/org/apache/activemq/apollo/openw...

Author: chirino
Date: Tue Feb 21 13:37:42 2012
New Revision: 1291776

URL: http://svn.apache.org/viewvc?rev=1291776&view=rev
Log:
Fixes APLO-165 : Enhance the access control rules to allow matching against the connector the user is connected against.

Modified:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java
    activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala
    activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
    activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
    activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
    activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
    activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala Tue Feb 21 13:37:42 2012
@@ -196,13 +196,23 @@ object Authorizer {
       case principal_kind => Some(principal_kind.split("\\s").map(_.trim()).toSet)
     }
 
+    def connector_match(func:(SecurityContext)=>Boolean):(SecurityContext)=>Boolean = {
+      Option(rule.connector).getOrElse("*") match {
+        case "*" => func
+        case connector_id =>
+          (ctx:SecurityContext) => {
+            ctx.connector_id==connector_id && func(ctx)
+          }
+      }
+    }
+    
     def parse_principals(value:String): Option[(SecurityContext)=>Boolean] = {
       Option(value).map(_.trim() match {
         case "*" =>
-          ((ctx:SecurityContext) => { true })
+          connector_match((ctx:SecurityContext) => { true })
         case "+" =>
           // user has to have at least one of the principle kinds
-          ((ctx:SecurityContext) => {
+          connector_match((ctx:SecurityContext) => {
             principal_kinds match {
               case Some(principal_kinds)=>
                 ctx.principals.find(p=> principal_kinds.contains(p.getClass.getName) ).isDefined
@@ -216,7 +226,7 @@ object Authorizer {
           } else {
             Set(principal)
           }
-          ((ctx:SecurityContext) => {
+          connector_match((ctx:SecurityContext) => {
             principal_kinds match {
               case Some(principal_kinds)=>
                 ctx.principals.find{ p=>

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala Tue Feb 21 13:37:42 2012
@@ -36,6 +36,7 @@ class SecurityContext {
   var password:String = _
   var sso_token:String = _
   var certificates:Array[X509Certificate] = _
+  var connector_id:String = _
   var local_address:SocketAddress = _
   var remote_address:SocketAddress = _
   var login_context:LoginContext = _

Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java Tue Feb 21 13:37:42 2012
@@ -87,6 +87,13 @@ public class AccessRuleDTO {
     public String id;
 
     /**
+     * The id of the connector the user must be connected on for the
+     * rule to match. You can use `*` to match all connectors. Defaults to `*`.
+     */
+    @XmlAttribute
+    public String connector;
+
+    /**
      * A regular expression used to match the id of the resource.
      */
     @XmlAttribute(name = "id_regex")
@@ -114,6 +121,8 @@ public class AccessRuleDTO {
             return false;
         if (separator != null ? !separator.equals(that.separator) : that.separator != null)
             return false;
+        if (connector != null ? !connector.equals(that.connector) : that.connector != null)
+            return false;
 
         return true;
     }
@@ -128,6 +137,7 @@ public class AccessRuleDTO {
         result = 31 * result + (kind != null ? kind.hashCode() : 0);
         result = 31 * result + (id != null ? id.hashCode() : 0);
         result = 31 * result + (id_regex != null ? id_regex.hashCode() : 0);
+        result = 31 * result + (connector != null ? connector.hashCode() : 0);
         return result;
     }
 
@@ -150,6 +160,7 @@ public class AccessRuleDTO {
             attr("kind",kind)+
             attr("id",kind)+
             attr("id_regex",id_regex)+
+            attr("connector",connector)+
             "/>";
     }
 }

Modified: activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala Tue Feb 21 13:37:42 2012
@@ -194,6 +194,7 @@ class OpenwireProtocolHandler extends Pr
     connection_log = connection.connector.broker.connection_log
     security_context.local_address = connection.transport.getLocalAddress
     security_context.remote_address = connection.transport.getRemoteAddress
+    security_context.connector_id = connection.connector.id
 
     sink_manager = new SinkMux[Command]( connection.transport_sink.map {x=>
       x.setCommandId(next_command_id)

Modified: activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala Tue Feb 21 13:37:42 2012
@@ -856,6 +856,7 @@ class StompProtocolHandler extends Proto
     security_context.remote_address = connection.transport.getRemoteAddress
     security_context.user = get(headers, LOGIN).map(decode_header _).getOrElse(null)
     security_context.password = get(headers, PASSCODE).map(decode_header _).getOrElse(null)
+    security_context.connector_id = connection.connector.id
 
     val accept_versions = get(headers, ACCEPT_VERSION).getOrElse(V1_0).split(COMMA).map(_.ascii)
     protocol_version = SUPPORTED_PROTOCOL_VERSIONS.find( v=> accept_versions.contains(v) ) match {

Modified: activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml Tue Feb 21 13:37:42 2012
@@ -33,6 +33,10 @@
   <access_rule allow="guest" action="connect"/>
   <access_rule allow="guest" action="create destroy send receive consume" kind="topic queue dsub" id_regex="test.*"/>
 
+  <!-- only allow connects over the tcp2 connector -->
+  <access_rule allow="connector_restricted" action="connect" connector="tcp2"/>
+
+
   <virtual_host id="default">
     <host_name>localhost</host_name>
   </virtual_host>
@@ -40,5 +44,7 @@
   <connector id="tcp" bind="tcp://0.0.0.0:0">
     <stomp add_user_header="JMSXUserID"/>
   </connector>
+  <connector id="tcp2" bind="tcp://0.0.0.0:0">
+  </connector>
 
 </broker>
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties Tue Feb 21 13:37:42 2012
@@ -20,6 +20,7 @@ connect_group=CN=ssl_user|can_only_conne
 guest=guest
 can_not_connect=can_not_connect
 can_only_connect=can_only_connect
+connector_restricted=connector_restricted
 
 #
 # Users with specific roles related to queues

Modified: activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala Tue Feb 21 13:37:42 2012
@@ -59,8 +59,11 @@ class StompTestSupport extends FunSuiteS
     clients = Nil
   }
 
-  def connect_request(version:String, c: StompClient, headers:String="") = {
-    c.open("localhost", port)
+  def connect_request(version:String, c: StompClient, headers:String="", connector:String=null) = {
+    val p = Option(connector).map{ id =>
+      broker.connectors.get(id).map(_.socket_address.asInstanceOf[InetSocketAddress].getPort).getOrElse(port)
+    }.getOrElse(port)
+    c.open("localhost", p)
     version match {
       case "1.0"=>
         c.write(
@@ -80,8 +83,8 @@ class StompTestSupport extends FunSuiteS
     c.receive()
   }
 
-  def connect(version:String, c: StompClient = client, headers:String="") = {
-    val frame = connect_request(version, c, headers)
+  def connect(version:String, c: StompClient = client, headers:String="", connector:String=null) = {
+    val frame = connect_request(version, c, headers, connector)
     frame should startWith("CONNECTED\n")
     frame should include regex("""session:.+?\n""")
     frame should include("version:"+version+"\n")
@@ -1904,6 +1907,20 @@ class StompSecurityTest extends StompTes
 
   }
 
+  test("Connector restricted user on the right connector") {
+    connect("1.1", client,
+      "login:connector_restricted\n" +
+      "passcode:connector_restricted\n", "tcp2")
+  }
+
+  test("Connector restricted user on the wrong connector") {
+    val frame = connect_request("1.1", client,
+      "login:connector_restricted\n" +
+      "passcode:connector_restricted\n", "tcp")
+    frame should startWith("ERROR\n")
+    frame should include("message:Not authorized to connect to connector 'tcp'.")
+  }
+
   test("Send not authorized") {
     connect("1.1", client,
       "login:can_only_connect\n" +

Modified: activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md (original)
+++ activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md Tue Feb 21 13:37:42 2012
@@ -710,6 +710,9 @@ an authorization check:
 * `id_regex`: A regular expression to be applied against the id of the
   resource.
 
+* `connector`: The id of the connector the user must be connected on for the
+  rule to match. You can use `*` to match all connectors. Defaults to `*`.
+
 If no access rules match an authorization check then access is denied. 
 
 ##### Ordering