activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r1034235 - in /activemq/activemq-apollo/trunk: ./ apollo-broker/ apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/ apollo-dto/src/main/java/org/apache/activemq/apollo/dto/
Date Fri, 12 Nov 2010 01:27:33 GMT
Author: chirino
Date: Fri Nov 12 01:27:32 2010
New Revision: 1034235

URL: http://svn.apache.org/viewvc?rev=1034235&view=rev
Log:
laying down the initial framework for pluggable security.

Added:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthenticatorFactory.scala
    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/AuthorizerFactory.scala
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.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/AuthenticatorDTO.java
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthorizerDTO.java
Modified:
    activemq/activemq-apollo/trunk/apollo-broker/pom.xml
    activemq/activemq-apollo/trunk/pom.xml

Modified: activemq/activemq-apollo/trunk/apollo-broker/pom.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/pom.xml?rev=1034235&r1=1034234&r2=1034235&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/pom.xml (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/pom.xml Fri Nov 12 01:27:32 2010
@@ -56,6 +56,12 @@
       <version>${hawtdispatch-version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.activemq</groupId>
+      <artifactId>activemq-jaas</artifactId>
+      <version>${activemq-version}</version>
+    </dependency>
+
     <!-- Scala Support -->
     <dependency>
       <groupId>org.scala-lang</groupId>

Added: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+import scala.util.continuations._
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+trait Authenticator {
+
+  /**
+   * If the authentication succeeds, then the subject and
+   * principles fields of the SecurityContext should be populated.
+   *
+   * @returns true if the SecurityContext was authenticated.
+   */
+  def authenticate(ctx:SecurityContext):Boolean @suspendable
+
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthenticatorFactory.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthenticatorFactory.scala?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthenticatorFactory.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthenticatorFactory.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+
+import org.apache.activemq.apollo.dto._
+import org.apache.activemq.apollo.util._
+import ReporterLevel._
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+object AuthenticatorFactory {
+
+  trait Provider {
+    def create(config:AuthenticatorDTO):Authenticator
+    def validate(config: AuthenticatorDTO, reporter:Reporter):ReporterLevel
+  }
+
+  def discover = {
+    val finder = new ClassFinder[Provider]("META-INF/services/org.apache.activemq.apollo/authenticator-factory.index")
+    finder.new_instances
+  }
+
+  var providers = discover
+
+  def create(config:AuthenticatorDTO):Authenticator = {
+    if( config == null ) {
+      return null
+    }
+    providers.foreach { provider=>
+      val rc = provider.create(config)
+      if( rc!=null ) {
+        return rc
+      }
+    }
+    throw new IllegalArgumentException("Uknonwn store type: "+config.getClass)
+  }
+
+
+  def validate(config: AuthenticatorDTO, reporter:Reporter):ReporterLevel = {
+    if( config == null ) {
+      return INFO
+    } else {
+      providers.foreach { provider=>
+        val rc = provider.validate(config, reporter)
+        if( rc!=null ) {
+          return rc
+        }
+      }
+    }
+    reporter.report(ERROR, "Uknonwn store type: "+config.getClass)
+    ERROR
+  }
+
+}
\ No newline at end of file

Added: 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=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+class Authorizer {
+
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthorizerFactory.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthorizerFactory.scala?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthorizerFactory.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/AuthorizerFactory.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+
+import org.apache.activemq.apollo.dto._
+import org.apache.activemq.apollo.util._
+import ReporterLevel._
+
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+object AuthorizerFactory {
+
+  trait Provider {
+    def create(config:AuthorizerDTO):Authorizer
+    def validate(config: AuthorizerDTO, reporter:Reporter):ReporterLevel
+  }
+
+  def discover = {
+    val finder = new ClassFinder[Provider]("META-INF/services/org.apache.activemq.apollo/authorizer-factory.index")
+    finder.new_instances
+  }
+
+  var providers = discover
+
+  def create(config:AuthorizerDTO):Authorizer = {
+    if( config == null ) {
+      return null
+    }
+    providers.foreach { provider=>
+      val rc = provider.create(config)
+      if( rc!=null ) {
+        return rc
+      }
+    }
+    throw new IllegalArgumentException("Uknonwn store type: "+config.getClass)
+  }
+
+
+  def validate(config: AuthorizerDTO, reporter:Reporter):ReporterLevel = {
+    if( config == null ) {
+      return INFO
+    } else {
+      providers.foreach { provider=>
+        val rc = provider.validate(config, reporter)
+        if( rc!=null ) {
+          return rc
+        }
+      }
+    }
+    reporter.report(ERROR, "Uknonwn store type: "+config.getClass)
+    ERROR
+  }
+
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+
+import javax.security.auth.login.LoginContext
+
+import javax.security.auth.callback.Callback
+import javax.security.auth.callback.CallbackHandler
+import javax.security.auth.callback.NameCallback
+import javax.security.auth.callback.PasswordCallback
+import javax.security.auth.callback.UnsupportedCallbackException
+
+import org.apache.activemq.jaas._
+import org.apache.activemq.apollo.util.OptionSupport._
+import org.apache.activemq.apollo.broker.Broker.BLOCKABLE_THREAD_POOL
+import org.fusesource.hawtdispatch._
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+
+class JaasAuthenticator extends Authenticator {
+
+  var jass_realm: String = _
+
+  /*
+   * The 'BLOCKABLE_THREAD_POOL ! { ... }' magic makes the code block
+   * execute on the global thread pool since JAAS requests could
+   * potentially perform a blocking wait (e.g. LDAP request).
+   */
+  def authenticate(security_ctx: SecurityContext) = BLOCKABLE_THREAD_POOL ! {
+
+    val original = Thread.currentThread().getContextClassLoader()
+    Thread.currentThread().setContextClassLoader(getClass.getClassLoader())
+    try {
+
+      val login_ctx = new LoginContext(jass_realm, new CallbackHandler {
+        def handle(callbacks: Array[Callback]) = {
+          callbacks.foreach{ callback =>
+            callback match {
+              case x: NameCallback => x.setName(security_ctx.user)
+              case x: PasswordCallback => x.setPassword(security_ctx.password.getOrElse("").toCharArray)
+              case x: CertificateCallback => x.setCertificates(security_ctx.certificates)
+              case _ => throw new UnsupportedCallbackException(callback)
+            }
+          }
+        }
+      })
+
+      login_ctx.login()
+      security_ctx.subject = login_ctx.getSubject()
+      true
+    } catch {
+      case x:Exception =>
+      false
+    } finally {
+      Thread.currentThread().setContextClassLoader(original)
+    }
+  }
+
+
+}
\ No newline at end of file

Added: 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=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.broker.security
+
+import java.security.Principal
+import collection.mutable.HashSet
+import javax.security.auth.Subject
+import java.security.cert.X509Certificate
+import org.apache.activemq.apollo.util.OptionSupport._
+import org.apache.activemq.jaas.UserPrincipal
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+class SecurityContext {
+
+  var user:String = _
+  var password:String = _
+  var certificates = Array[X509Certificate]()
+
+  /**
+   * A place for the authorization layer attach
+   * some authorization data (i.e. an authorization
+   * cache)
+   */
+  var authorization_data:AnyRef = _
+
+  var subject:Subject = _
+
+  def principles = subject.map(x=>collection.JavaConversions.asSet(x.getPrincipals).toSet).getOrElse(Set())
+
+  def intersects(other_priciples:Set[Principal] ) = {
+    !principles.intersect(other_priciples).isEmpty
+  }
+
+  def principle[T](kind:Class[T]):Option[T] ={
+    principles.find( x=> kind.isAssignableFrom(x.getClass) ).map(kind.cast(_))
+  }
+
+  def user_principle = principle(classOf[UserPrincipal])
+}
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticatorDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticatorDTO.java?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticatorDTO.java
(added)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticatorDTO.java
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.dto;
+
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+@XmlType(name = "authenticator-type")
+//@XmlSeeAlso({xxx.class})
+@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
+public abstract class AuthenticatorDTO {
+
+
+}

Added: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthorizerDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthorizerDTO.java?rev=1034235&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthorizerDTO.java
(added)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthorizerDTO.java
Fri Nov 12 01:27:32 2010
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.activemq.apollo.dto;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import java.io.File;
+
+/**
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+@XmlType(name = "authorizer-type")
+//@XmlSeeAlso({xxx.class})
+@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
+public abstract class AuthorizerDTO {
+
+
+}

Modified: activemq/activemq-apollo/trunk/pom.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/pom.xml?rev=1034235&r1=1034234&r2=1034235&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/pom.xml (original)
+++ activemq/activemq-apollo/trunk/pom.xml Fri Nov 12 01:27:32 2010
@@ -37,7 +37,6 @@
     <website-base-url>scp://people.apache.org/x1/www/activemq.apache.org/apollo</website-base-url>
 
     <target-dir>target</target-dir>
-    <apollo-version>6.0-SNAPSHOT</apollo-version>
     <projectName>Apache Apollo</projectName>
 
     <!-- dependencies that track scala version changes -->
@@ -45,6 +44,7 @@
     <scalatest-version>1.2</scalatest-version>
     <cascal-version>1.3-SNAPSHOT</cascal-version>
     
+    <activemq-version>5.4.1</activemq-version>
     <servicemix.kernel.version>1.1.0</servicemix.kernel.version>
     <spring-version>2.5.5</spring-version>
     <activesoap-version>1.3</activesoap-version>



Mime
View raw message