perfsonar-dev - perfsonar: r2751 - in trunk/perfsonar: ant ant/as conf doc doc/as schema/example-instances/perfSONAR/AS/test src/org/perfsonar/client/commons/authn src/org/perfsonar/client/commons/authn/edugain src/org/perfsonar/client/commons/authn/edugain/mds src/org/perfsonar/client/commons/authn/saslca src/org/perfsonar/client/commons/requests src/org/perfsonar/client/commons/requests/authService src/org/perfsonar/client/testHarness src/org/perfsonar/commons/auxiliary/components/authn/wssec src/org/perfsonar/commons/messages src/org/perfsonar/service/authService src/org/perfsonar/service/commons/authn src/org/perfsonar/service/commons/engine src/org/perfsonar/service/testHarness/authService src/org/perfsonar/service/web
Subject: perfsonar development work
List archive
perfsonar: r2751 - in trunk/perfsonar: ant ant/as conf doc doc/as schema/example-instances/perfSONAR/AS/test src/org/perfsonar/client/commons/authn src/org/perfsonar/client/commons/authn/edugain src/org/perfsonar/client/commons/authn/edugain/mds src/org/perfsonar/client/commons/authn/saslca src/org/perfsonar/client/commons/requests src/org/perfsonar/client/commons/requests/authService src/org/perfsonar/client/testHarness src/org/perfsonar/commons/auxiliary/components/authn/wssec src/org/perfsonar/commons/messages src/org/perfsonar/service/authService src/org/perfsonar/service/commons/authn src/org/perfsonar/service/commons/engine src/org/perfsonar/service/testHarness/authService src/org/perfsonar/service/web
Chronological Thread
- From:
- To:
- Subject: perfsonar: r2751 - in trunk/perfsonar: ant ant/as conf doc doc/as schema/example-instances/perfSONAR/AS/test src/org/perfsonar/client/commons/authn src/org/perfsonar/client/commons/authn/edugain src/org/perfsonar/client/commons/authn/edugain/mds src/org/perfsonar/client/commons/authn/saslca src/org/perfsonar/client/commons/requests src/org/perfsonar/client/commons/requests/authService src/org/perfsonar/client/testHarness src/org/perfsonar/commons/auxiliary/components/authn/wssec src/org/perfsonar/commons/messages src/org/perfsonar/service/authService src/org/perfsonar/service/commons/authn src/org/perfsonar/service/commons/engine src/org/perfsonar/service/testHarness/authService src/org/perfsonar/service/web
- Date: Thu, 30 Aug 2007 07:30:06 -0400
Author: rodriguez
Date: 2007-08-30 07:30:05 -0400 (Thu, 30 Aug 2007)
New Revision: 2751
Added:
trunk/perfsonar/doc/as/
trunk/perfsonar/doc/as/AS_interface_specification.doc
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/EduGAINFilterHelper.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/EduGAINMetadataService.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/mds/
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/mds/BridgingElement.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/SASLCAClient.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/SASLCAClientConfiguration.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/UserID.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/UserIDCallbackHandler.java
trunk/perfsonar/src/org/perfsonar/client/commons/requests/authService/
trunk/perfsonar/src/org/perfsonar/client/commons/requests/authService/AuthNEERequestGenerator.java
trunk/perfsonar/src/org/perfsonar/client/testHarness/UbCMDSTest.java
trunk/perfsonar/src/org/perfsonar/client/testHarness/UbCSaslTest.java
trunk/perfsonar/src/org/perfsonar/commons/messages/AuthNEERequest.java
Removed:
trunk/perfsonar/conf/AuthNRequest.xml
trunk/perfsonar/src/org/perfsonar/commons/messages/AuthNClient.java
Modified:
trunk/perfsonar/ant/as/client-run-targets.xml
trunk/perfsonar/ant/as/configure-targets.xml
trunk/perfsonar/ant/as/libs-download-targets.xml
trunk/perfsonar/ant/as/test-run-targets.xml
trunk/perfsonar/ant/libs-download-targets.xml
trunk/perfsonar/schema/example-instances/perfSONAR/AS/test/AuthNRequest.xml
trunk/perfsonar/src/org/perfsonar/client/commons/authn/AuthNData.java
trunk/perfsonar/src/org/perfsonar/client/commons/authn/WSSAuthNData.java
trunk/perfsonar/src/org/perfsonar/commons/auxiliary/components/authn/wssec/WSSecAuthNComponent.java
trunk/perfsonar/src/org/perfsonar/service/authService/ASEngine.java
trunk/perfsonar/src/org/perfsonar/service/authService/AuthNAction.java
trunk/perfsonar/src/org/perfsonar/service/commons/authn/AADispatchSOAPProtocol.java
trunk/perfsonar/src/org/perfsonar/service/commons/engine/ActionType.java
trunk/perfsonar/src/org/perfsonar/service/testHarness/authService/AuthNRequestTest.java
trunk/perfsonar/src/org/perfsonar/service/web/RequestHandler.java
Log:
Authentication mechanisms improved:
- Library for UbC developers
+ Queries to eduGAIN MetaData Service
+ Certificate obtained from a SASL CA server
- Library for WE developers
- Classes for generating an AuthN request (no more using a XML file)
- Improving the AuthService
- Message types of authn request/response changed to
'AuthNEERequest/AuthNEEResponse'
Modified: trunk/perfsonar/ant/as/client-run-targets.xml
===================================================================
--- trunk/perfsonar/ant/as/client-run-targets.xml 2007-08-30 11:22:48
UTC (rev 2750)
+++ trunk/perfsonar/ant/as/client-run-targets.xml 2007-08-30 11:30:05
UTC (rev 2751)
@@ -2,6 +2,7 @@
<project name="as-psr-run-targets">
<property name="as.local"
value="http://${target.server}:${target.port}/${deploy.root}/services/${webservice.name}"/>
+ <property name="new.endorsed.libraries"
value="${basedir}/lib/repository/xalan/xalan/2.7.0/:${basedir}/lib/repository/xalan/xalan-serializer/2.7.0/:${basedir}/lib/repository/xerces/xercesImpl/2.8.0/:${basedir}/lib/repository/xerces/xerces-xml-apis/2.8.0/"/>
<target name="run-psr-x509-client" description="Runs Java client2">
@@ -32,7 +33,6 @@
<java
classname="org.perfsonar.service.testHarness.authService.AuthNRequestTest"
classpathref="classpath" fork="true">
<arg value="${as.local}"/>
- <arg
value="${basedir}/schema/example-instances/perfSONAR/AS/test/AuthNRequest.xml"/>
<arg value="${basedir}/conf/test-eduGAIN.key"/>
<arg value="${basedir}/conf/test-eduGAIN.pem"/>
<arg value="${basedir}/src/objects.config"/>
@@ -49,4 +49,44 @@
</target>
-</project>
\ No newline at end of file
+ <target name="run-ubc-mds" description="Runs Java client2">
+ <echo message="Executing test using endorsed directory
${new.endorsed.libraries}" />
+ <java classname="org.perfsonar.client.testHarness.UbCMDSTest"
+ classpathref="classpath" fork="true">
+ <jvmarg
value="-Djava.endorsed.dirs=${new.endorsed.libraries}"/>
+
+ <classpath>
+ <pathelement location="build/perfSONAR-generic.jar"/>
+ <pathelement location="build/perfSONAR-as.jar"/>
+ </classpath>
+
+ </java>
+
+ <echo>Test ended successfully.</echo>
+
+ </target>
+
+ <target name="run-ubc-saslca" description="Runs Java client2">
+ <java classname="org.perfsonar.client.testHarness.UbCSaslTest"
+ classpathref="classpath" fork="true">
+ <jvmarg value="-DuseSubjectCredsOnly=true"/>
+ <arg value="kanete.rediris.es"/>
+ <arg value="4088"/>
+ <arg value="/Users/kan/Projects/workspace/RedIRIS - perfSONAR
- SASL CA/apps/server/handle.jks"/>
+ <arg value="petete"/>
+ <arg value="jceks"/>
+ <arg value="username"/>
+ <arg value="password"/>
+
+ <classpath>
+ <pathelement location="build/perfSONAR-generic.jar"/>
+ <pathelement location="build/perfSONAR-as.jar"/>
+ </classpath>
+
+ </java>
+
+ <echo>Test ended successfully.</echo>
+
+ </target>
+
+</project>
Modified: trunk/perfsonar/ant/as/configure-targets.xml
===================================================================
--- trunk/perfsonar/ant/as/configure-targets.xml 2007-08-30 11:22:48
UTC (rev 2750)
+++ trunk/perfsonar/ant/as/configure-targets.xml 2007-08-30 11:30:05
UTC (rev 2751)
@@ -46,7 +46,7 @@
<entry key="service.log.log4j.config"
value="${basedir}/conf/log4j.properties"/>
<entry key="service.sax_parser.config"
value="${basedir}/src/objects.config"/>
- <entry key="service.as.message_types" value="AuthNClient"/>
+ <entry key="service.as.message_types" value="AuthNEERequest"/>
<entry key="service.as.class_name"
value="org.perfsonar.service.authService.ASEngine"/>
<entry key="service.as.truststore_file"
value="${basedir}/conf/perfSONARtruststore.jks"/>
<entry key="service.as.crypt_provider" value="SunRsaSign"/>
Modified: trunk/perfsonar/ant/as/libs-download-targets.xml
===================================================================
--- trunk/perfsonar/ant/as/libs-download-targets.xml 2007-08-30 11:22:48
UTC (rev 2750)
+++ trunk/perfsonar/ant/as/libs-download-targets.xml 2007-08-30 11:30:05
UTC (rev 2751)
@@ -1,19 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="../" name="as-libs-download-targets"
xmlns:artifact="urn:maven-artifact-ant">
- <target name="libs-for-as" depends="init-libs">
- <artifact:dependencies>
- <dependency groupId="opensaml" artifactId="opensaml"
version="1.1"/>
- <dependency groupId="edugain" artifactId="edugain"
version="0.5"/>
-
- <localRepository refid="local.repository"/>
- <remoteRepository refid="remote.repository"/>
- </artifact:dependencies>
- </target>
-
<target name="libs-as">
<antcall target="libs-generic"/>
- <antcall target="libs-for-as"/>
</target>
</project>
\ No newline at end of file
Modified: trunk/perfsonar/ant/as/test-run-targets.xml
===================================================================
--- trunk/perfsonar/ant/as/test-run-targets.xml 2007-08-30 11:22:48 UTC (rev
2750)
+++ trunk/perfsonar/ant/as/test-run-targets.xml 2007-08-30 11:30:05 UTC (rev
2751)
@@ -3,6 +3,8 @@
<target name="test">
<antcall target="run-psr-x509-client"/>
<antcall target="run-psr-x509-service"/>
+ <antcall target="run-ubc-mds"/>
+ <antcall target="run-ubc-saslca"/>
</target>
-</project>
\ No newline at end of file
+</project>
Modified: trunk/perfsonar/ant/libs-download-targets.xml
===================================================================
--- trunk/perfsonar/ant/libs-download-targets.xml 2007-08-30 11:22:48
UTC (rev 2750)
+++ trunk/perfsonar/ant/libs-download-targets.xml 2007-08-30 11:30:05
UTC (rev 2751)
@@ -43,23 +43,25 @@
<dependency groupId="axis"
artifactId="axis-jaxrpc" version="1.4"/>
<dependency groupId="axis"
artifactId="axis-saaj" version="1.4"/>
<dependency groupId="axis"
artifactId="axis-ant" version="1.4"/>
- <dependency groupId="xerces"
artifactId="xercesImpl" version="2.6.2"/>
- <dependency groupId="xerces"
artifactId="xmlParserAPIs" version="2.6.2"/>
+ <dependency groupId="xerces"
artifactId="xercesImpl" version="2.8.0"/>
+ <dependency groupId="xerces"
artifactId="xerces-xml-apis" version="2.8.0"/>
<dependency groupId="xml-apis"
artifactId="xml-apis" version="1.3.02"/>
<dependency groupId="jdom" artifactId="jdom"
version="1.0b8"/>
<dependency groupId="urbanophile"
artifactId="java-getopt" version="1.0.9"/>
<dependency groupId="junit" artifactId="junit"
version="4.0"/>
<dependency groupId="xalan" artifactId="xalan"
version="2.7.0"/>
+ <dependency groupId="xalan"
artifactId="xalan-serializer" version="2.7.0"/>
<dependency groupId="commons-pool"
artifactId="commons-pool" version="1.1"/>
<dependency groupId="commons-collections"
artifactId="commons-collections" version="3.2"/>
<dependency groupId="commons-beanutils"
artifactId="commons-beanutils" version="1.7.0"/>
+ <dependency groupId="commons-lang"
artifactId="commons-lang" version="2.3"/>
<dependency groupId="javax.activation"
artifactId="activation" version="1.0.2"/>
<dependency groupId="javax.mail" artifactId="mail"
version="1.3.2"/>
<dependency groupId="tomcat"
artifactId="servlet-api" version="5.0.28"/>
- <dependency groupId="log4j" artifactId="log4j"
version="1.2.9"/>
+ <dependency groupId="log4j" artifactId="log4j"
version="1.2.13"/>
<dependency groupId="exist"
artifactId="exist-xmldb" version="1.0rc"/>
<dependency groupId="exist"
artifactId="exist-db" version="1.0rc"/>
@@ -69,6 +71,13 @@
<dependency groupId="xml-security" artifactId="xmlsec"
version="1.3.0"/>
<dependency groupId="bouncycastle"
artifactId="bcprov-jdk15" version="124"/>
<dependency groupId="wss4j" artifactId="wss4j"
version="1.5.1"/>
+ <dependency groupId="javolution"
artifactId="javolution" version="3.7"/>
+ <dependency groupId="opensaml"
artifactId="opensaml" version="2.0-TP2-jdk-1.5"/>
+ <dependency groupId="xmltooling"
artifactId="xmltooling" version="1.0-TP2-jdk-1.5"/>
+ <dependency groupId="opensaml"
artifactId="opensaml" version="1.1"/>
+ <dependency groupId="edugain"
artifactId="edugain" version="0.5"/>
+ <dependency groupId="sasl-ca"
artifactId="sasl-ca" version="1.0"/>
+ <dependency groupId="codec"
artifactId="codec" version="1.0"/>
<dependency groupId="joda-time"
artifactId="joda-time" version="1.4"/>
Deleted: trunk/perfsonar/conf/AuthNRequest.xml
Added: trunk/perfsonar/doc/as/AS_interface_specification.doc
Property changes on: trunk/perfsonar/doc/as/AS_interface_specification.doc
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified:
trunk/perfsonar/schema/example-instances/perfSONAR/AS/test/AuthNRequest.xml
===================================================================
---
trunk/perfsonar/schema/example-instances/perfSONAR/AS/test/AuthNRequest.xml
2007-08-30 11:22:48 UTC (rev 2750)
+++
trunk/perfsonar/schema/example-instances/perfSONAR/AS/test/AuthNRequest.xml
2007-08-30 11:30:05 UTC (rev 2751)
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<nmwg:message id="authNMessage1" type="AuthNClient"
xmlns:nmwg="http://ggf.org/ns/nmwg/base/2.0/">
+<nmwg:message id="authNMessage1" type="AuthNEERequest"
xmlns:nmwg="http://ggf.org/ns/nmwg/base/2.0/">
<nmwg:metadata id="authNMetadata">
<nmwg:parameters id="keys">
<nmwg:parameter
name="SecurityToken">http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</nmwg:parameter>
Modified:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/AuthNData.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/client/commons/authn/AuthNData.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/client/commons/authn/AuthNData.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -3,9 +3,11 @@
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
+import org.opensaml.SAMLAssertion;
import org.perfsonar.service.commons.exceptions.PerfSONARException;
public interface AuthNData {
public Object addX509STInMessage(Object message,String
privKeyFile,String certFile) throws PerfSONARException;
public Object addX509STInMessage(Object message,PrivateKey
privateKey,X509Certificate cert) throws PerfSONARException;
+ public Object addSAMLSTInMessage(Object message,SAMLAssertion
authAssertion,PrivateKey key,X509Certificate cert,String
cidPerfsonarResource,String cidPerfsonarClient) throws PerfSONARException;
}
Modified:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/WSSAuthNData.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/client/commons/authn/WSSAuthNData.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/client/commons/authn/WSSAuthNData.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -13,6 +13,8 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Date;
import java.util.Vector;
import org.apache.axis.Message;
@@ -24,22 +26,34 @@
import org.apache.ws.security.components.crypto.CredentialException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSAMLToken;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
+import org.apache.xml.security.signature.XMLSignature;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLAudienceRestrictionCondition;
+import org.opensaml.SAMLAuthenticationStatement;
+import org.opensaml.SAMLException;
+import org.opensaml.SAMLSubject;
+import org.opensaml.XML;
import org.perfsonar.commons.auxiliary.components.authn.DynamicCrypto;
import org.perfsonar.commons.auxiliary.components.authn.SOAPUtil;
import org.perfsonar.service.commons.exceptions.PerfSONARException;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
public class WSSAuthNData implements AuthNData {
+ private String sigalg = XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;
+ private String digalg = MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1;
public Object addX509STInMessage(Object message,String
privKeyFile,String certFile) throws PerfSONARException {
if (!(message instanceof SOAPBodyElement)) {
throw new
PerfSONARException("error.as.body","WSSAuthNData: the method
addX509STInMessage requires a SOAPBodyElement object");
}
-
+
// add the security provider
BouncyCastleProvider bcp = new BouncyCastleProvider();
java.security.Security.addProvider((Provider)bcp);
@@ -54,10 +68,10 @@
X509Certificate cert=addCertificate(crypto,certFile);
PrivateKey privateKey=addPrivateKey(privKeyFile);
-
+
return addX509STInMessage(message, privateKey, cert);
}
-
+
public Object addX509STInMessage(Object message,PrivateKey
privateKey,X509Certificate cert) throws PerfSONARException {
if (!(message instanceof SOAPBodyElement)) {
throw new
PerfSONARException("error.as.body","WSSAuthNData: the method
addX509STInMessage requires a SOAPBodyElement object");
@@ -65,11 +79,11 @@
SOAPBodyElement body=(SOAPBodyElement)message;
SOAPEnvelope envelope = new SOAPEnvelope();
envelope.addBodyElement(body);
-
+
// add the security provider
BouncyCastleProvider bcp = new BouncyCastleProvider();
java.security.Security.addProvider((Provider)bcp);
-
+
Crypto crypto = null;
try {
crypto = new DynamicCrypto();
@@ -104,9 +118,9 @@
Document doc = envelope.getAsDocument();
WSSecHeader secHeader = new WSSecHeader();
- secHeader.setActor("test");
+ secHeader.setActor("ac");
secHeader.insertSecurityHeader(doc);
-
+
// Signing the message
Document signedDoc = sec509.build(doc, crypto, secHeader);
@@ -118,7 +132,7 @@
return envelope;
}
-
+
private PrivateKey addPrivateKey(String privKeyFile) throws
PerfSONARException {
try {
BufferedReader in = new BufferedReader(new
FileReader(privKeyFile));
@@ -141,17 +155,75 @@
throw new
PerfSONARException("error.as.getting_privkey","WSSAuthNData:
"+e.getMessage());
}
}
-
+
private X509Certificate addCertificate(Crypto crypto,String certFile)
throws PerfSONARException {
try {
InputStream isCert=new FileInputStream(certFile);
-
+
X509Certificate cert=crypto.loadCertificate(isCert);
-
+
return cert;
} catch (Exception e) {
throw new
PerfSONARException("error.as.getting_cert","WSSAuthNData: "+e.getMessage());
}
}
+ public Object addSAMLSTInMessage(Object message,SAMLAssertion
assertion,PrivateKey key,X509Certificate cert,String
cidPerfsonarResource,String cidPerfsonarClient) throws PerfSONARException {
+ if (!(message instanceof SOAPBodyElement)) {
+ throw new
PerfSONARException("error.as.body","WSSAuthNData: the method
addX509STInMessage requires a SOAPBodyElement object");
+ }
+ SOAPBodyElement body=(SOAPBodyElement)message;
+ SOAPEnvelope envelope = new SOAPEnvelope();
+ envelope.addBodyElement(body);
+
+ try {
+ Document doc = envelope.getAsDocument();
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.setActor("we");
+ secHeader.insertSecurityHeader(doc);
+
+ WSSecSAMLToken samlToken = new WSSecSAMLToken();
+ Document signedDoc = samlToken.build(doc,
getAssertionAsSecurityToken(assertion, key, cert, cidPerfsonarResource,
cidPerfsonarClient), secHeader);
+ Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+ envelope = signedMsg.getSOAPEnvelope();
+ } catch (Exception e) {
+ throw new
PerfSONARException("error.as.signing","WSSAuthNData: "+e.getMessage());
+ }
+
+ return envelope;
+ }
+
+ private SAMLAssertion getAssertionAsSecurityToken(SAMLAssertion
authAssertion,PrivateKey key,X509Certificate cert,String
cidPerfsonarResource,String cidPerfsonarClient) throws SAMLException {
+ SAMLAssertion authStatementAssertion=new SAMLAssertion();
+
+ // Adding the client information
+ SAMLAudienceRestrictionCondition cond=new
SAMLAudienceRestrictionCondition();
+ cond.addAudience(cidPerfsonarResource);
+ authStatementAssertion.addCondition(cond);
+ authStatementAssertion.setIssuer(cidPerfsonarClient);
+
+ SAMLSubject subject=new SAMLSubject();
+ subject.addConfirmationMethod("relayed-trust");
+ try {
+ Document request =
authAssertion.toDOM().getOwnerDocument();
+
+ Element c=request.createElementNS(XML.SAML_NS,
"SubjectConfirmationData");
+ c.appendChild(authAssertion.toDOM());
+
+ subject.setConfirmationData(c);
+ } catch (Exception pce) {
+ pce.printStackTrace();
+ }
+
+ SAMLAuthenticationStatement authStatement=new
SAMLAuthenticationStatement();
+
authStatement.setAuthMethod(SAMLAuthenticationStatement.AuthenticationMethod_Unspecified);
+ authStatement.setAuthInstant(new Date());
+ authStatement.setSubject(subject);
+ authStatementAssertion.addStatement(authStatement);
+
+ authStatementAssertion.sign(sigalg, digalg, key,
Arrays.asList(cert));
+
+ return authStatementAssertion;
+ }
+
}
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/EduGAINFilterHelper.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/EduGAINMetadataService.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/edugain/mds/BridgingElement.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/SASLCAClient.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/SASLCAClientConfiguration.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/UserID.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/authn/saslca/UserIDCallbackHandler.java
Added:
trunk/perfsonar/src/org/perfsonar/client/commons/requests/authService/AuthNEERequestGenerator.java
Added: trunk/perfsonar/src/org/perfsonar/client/testHarness/UbCMDSTest.java
Added: trunk/perfsonar/src/org/perfsonar/client/testHarness/UbCSaslTest.java
Modified:
trunk/perfsonar/src/org/perfsonar/commons/auxiliary/components/authn/wssec/WSSecAuthNComponent.java
===================================================================
---
trunk/perfsonar/src/org/perfsonar/commons/auxiliary/components/authn/wssec/WSSecAuthNComponent.java
2007-08-30 11:22:48 UTC (rev 2750)
+++
trunk/perfsonar/src/org/perfsonar/commons/auxiliary/components/authn/wssec/WSSecAuthNComponent.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -50,8 +50,13 @@
throw new PerfSONARException(m);
}
try {
- String
checkAuthNParam=configuration.getProperty(AuthNComponent.CHECK_AUTHN_PARAM);
- if (checkAuthNParam.equals(AuthNComponent.YES_CHECK_AUTHN)) {
+ String checkAuthNParam=null;
+ try {
+
checkAuthNParam=configuration.getProperty(AuthNComponent.CHECK_AUTHN_PARAM);
+ } catch (PerfSONARException e) {
+ checkAuthNParam=null;
+ }
+ if
(checkAuthNParam!=null&&checkAuthNParam.equals(AuthNComponent.YES_CHECK_AUTHN))
{
checkAuthN = true;
String
listMsgsParam=configuration.getProperty(AuthNComponent.LIST_MSG_AUTHN);
StringTokenizer st=new
StringTokenizer(listMsgsParam,",");
Deleted: trunk/perfsonar/src/org/perfsonar/commons/messages/AuthNClient.java
Copied:
trunk/perfsonar/src/org/perfsonar/commons/messages/AuthNEERequest.java (from
rev 2694, trunk/perfsonar/src/org/perfsonar/commons/messages/AuthNClient.java)
Modified: trunk/perfsonar/src/org/perfsonar/service/authService/ASEngine.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/service/authService/ASEngine.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/service/authService/ASEngine.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -27,7 +27,7 @@
private eduGAINvalidator val;
public ASEngine() throws PerfSONARException {
- this.acceptedTypes = Arrays.asList(new String[] {
ActionType.AUTHN_CLIENT });
+ this.acceptedTypes = Arrays.asList(new String[] {
ActionType.AUTHN_EE_REQUEST });
// get logger
logger = (LoggerComponent)
AuxiliaryComponentManager.getInstance()
@@ -85,7 +85,7 @@
ASAction action = null;
// Take an action
- if (actionType.equals(ActionType.AUTHN_CLIENT)) {
+ if (actionType.equals(ActionType.AUTHN_EE_REQUEST)) {
action = new AuthNAction(val);
}
Modified:
trunk/perfsonar/src/org/perfsonar/service/authService/AuthNAction.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/service/authService/AuthNAction.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/service/authService/AuthNAction.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -9,14 +9,17 @@
import org.ggf.ns.nmwg.base.v2_0.Message;
import org.ggf.ns.nmwg.base.v2_0.Metadata;
import org.ggf.ns.nmwg.base.v2_0.Parameter;
+import org.opensaml.SAMLAssertion;
import org.perfsonar.service.commons.authn.tokens.SecTokenManagerFactory;
import org.perfsonar.service.commons.authn.tokens.SecurityToken;
import org.perfsonar.service.commons.exceptions.PerfSONARException;
+import org.w3c.dom.Element;
public class AuthNAction extends ASAction {
public static final String
X509_ID="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
+ public static final String
SAML_ID="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1";
- private static String TYPE_RESPONSE = "AuthNResponse";
+ private static String TYPE_RESPONSE = "AuthNEEResponse";
private static String EVENT_TYPE_SUCCESS = "success.as.authn";
private static String SEC_TOKEN_PARAM = "SecurityToken";
private eduGAINvalidator val;
@@ -42,6 +45,11 @@
sentSecToken.getParameterValue().equals(AuthNAction.X509_ID)) {
return processX509AuthN(request);
}
+ else if (sentSecToken!=null&&
+
sentSecToken.getParameterValue()!=null&&
+
sentSecToken.getParameterValue().equals(AuthNAction.SAML_ID)) {
+ return processSAMLAuthN(request);
+ }
else {
String m = "AuthNAction: Wrong parameter in
metadata";
logger.info(m);
@@ -49,7 +57,30 @@
}
}
}
+
+ private Message processSAMLAuthN(Message request) throws
PerfSONARException {
+ logger.debug("AuthNAction: Processing the authN using the
SAML assertion");
+ SecurityToken st=new
SecurityToken(SecTokenManagerFactory.getDefaultSecTokenManager());
+ st.setSecTokenFromRequest();
+ Object stValue=st.getSecTokenValue();
+ if (stValue==null) {
+ String m = "AuthNAction: the SAML assertion is not
included";
+ logger.info(m);
+ throw new
PerfSONARException("error.authn.assertion_not_included",m);
+ }
+ logger.debug("AuthNAction: Getting the SAML assertion");
+ try {
+ SAMLAssertion assertion=(SAMLAssertion)stValue;
+ val.validate((Element)assertion.toDOM());
+ } catch (Throwable e) {
+ String m = "AuthNAction: the SAML assertion is not
valid";
+ logger.info(m);
+ throw new
PerfSONARException("error.authn.assertion_not_valid",m);
+ }
+ return getValidAuthNMessage(request);
+ }
+
private Message processX509AuthN(Message request) throws
PerfSONARException {
logger.debug("AuthNAction: Processing the authN using the
X509 certificate");
SecurityToken st=new
SecurityToken(SecTokenManagerFactory.getDefaultSecTokenManager());
@@ -76,18 +107,14 @@
private Message getValidAuthNMessage(Message request) {
Message response = new Message();
-// response.setId("id1");
response.setType(TYPE_RESPONSE);
Metadata responseMetadata=new Metadata();
-// responseMetadata.setId("id2");
EventType et=new EventType();
responseMetadata.setEventType(et);
et.setEventType(EVENT_TYPE_SUCCESS);
Data responseData = new Data();
-// responseData.setId("id3");
-//
responseData.setMetadataIdRef(getMetadataFromRequest(request).getId());
responseData.setMetadataIdRef(responseMetadata.getId());
response.addChild(responseData);
response.setMetadata(responseMetadata);
Modified:
trunk/perfsonar/src/org/perfsonar/service/commons/authn/AADispatchSOAPProtocol.java
===================================================================
---
trunk/perfsonar/src/org/perfsonar/service/commons/authn/AADispatchSOAPProtocol.java
2007-08-30 11:22:48 UTC (rev 2750)
+++
trunk/perfsonar/src/org/perfsonar/service/commons/authn/AADispatchSOAPProtocol.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -1,6 +1,5 @@
package org.perfsonar.service.commons.authn;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.net.URL;
@@ -17,6 +16,7 @@
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.utils.XMLUtils;
import org.ggf.ns.nmwg.base.v2_0.Message;
+import
org.perfsonar.client.commons.requests.authService.AuthNEERequestGenerator;
import org.perfsonar.commons.auxiliary.AuxiliaryComponentManager;
import org.perfsonar.commons.auxiliary.ComponentNames;
import
org.perfsonar.commons.auxiliary.components.configuration.ConfigurationComponent;
@@ -30,12 +30,10 @@
public static final String
WSS_X509="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
public static final String
WSS_SAML="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1";
private final String AS_POINT_PARAM = "service.as.point";
- private final String FILE_AUTHN_PARAM = "service.as.authnRequest";
private final String SAX_PARSER_CONFIG = "service.sax_parser.config";
private LoggerComponent logger;
private ConfigurationComponent config;
private String asPoint;
- private String fileAuthnRequest;
private String saxParser;
public AADispatchSOAPProtocol() throws PerfSONARException {
@@ -57,7 +55,6 @@
}
try {
asPoint=config.getProperty(AS_POINT_PARAM);
- fileAuthnRequest=config.getProperty(FILE_AUTHN_PARAM);
saxParser=config.getProperty(SAX_PARSER_CONFIG);
} catch (Exception e) {
String m = "AADispatchSOAPProtocol: Can't obtain
required parameters ";
@@ -66,7 +63,7 @@
}
}
- public AADispatchSOAPProtocol(String asPoint, String
fileAuthnRequest, String saxParser) throws PerfSONARException {
+ public AADispatchSOAPProtocol(String asPoint, String saxParser)
throws PerfSONARException {
try {
logger = (LoggerComponent)
AuxiliaryComponentManager.getInstance()
.getComponent(ComponentNames.LOGGER);
@@ -75,13 +72,11 @@
throw new PerfSONARException(m);
}
this.asPoint=asPoint;
- this.fileAuthnRequest=fileAuthnRequest;
this.saxParser=saxParser;
}
public AuthNResponse getAuthentication(AuthNRequest req) throws
PerfSONARException {
AuthNResponse resp=new AuthNResponse();
- StringWriter outWriter = null;
// prepare to call - set service elements
try {
Service service = new Service();
@@ -90,12 +85,13 @@
call.setOperationName(new
QName("http://soapinterop.org/","submit"));
// read the request into a org.w3c.DOM.Document
- Document request = null;
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder =
factory.newDocumentBuilder();
- request = builder.parse(new File(fileAuthnRequest));
+ Document request = builder.newDocument();
+ Message authnRequest = new
AuthNEERequestGenerator().generateRequestMessage();
+ request = authnRequest.getDOM(request);
// get the parameter which specifies the format of
the security token
Element parameter=null;
Modified:
trunk/perfsonar/src/org/perfsonar/service/commons/engine/ActionType.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/service/commons/engine/ActionType.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/service/commons/engine/ActionType.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -122,7 +122,7 @@
* Action type to request the authentication of the client/user
*/
- public static final String AUTHN_CLIENT = "AuthNClient";
+ public static final String AUTHN_EE_REQUEST = "AuthNEERequest";
} //ActionType
Modified:
trunk/perfsonar/src/org/perfsonar/service/testHarness/authService/AuthNRequestTest.java
===================================================================
---
trunk/perfsonar/src/org/perfsonar/service/testHarness/authService/AuthNRequestTest.java
2007-08-30 11:22:48 UTC (rev 2750)
+++
trunk/perfsonar/src/org/perfsonar/service/testHarness/authService/AuthNRequestTest.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -1,6 +1,6 @@
package org.perfsonar.service.testHarness.authService;
-import java.io.File;
+import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.util.Iterator;
@@ -20,82 +20,137 @@
import org.ggf.ns.nmwg.base.v2_0.Message;
import org.perfsonar.client.commons.authn.AuthNData;
import org.perfsonar.client.commons.authn.AuthNDataFactory;
+import
org.perfsonar.client.commons.requests.authService.AuthNEERequestGenerator;
import org.perfsonar.service.commons.authn.AADispatchManager;
import org.perfsonar.service.commons.authn.AADispatchProtocol;
+import org.perfsonar.service.commons.authn.AADispatchSOAPProtocol;
import org.perfsonar.service.commons.authn.AuthNRequest;
import org.perfsonar.service.commons.authn.AuthNResponse;
import org.perfsonar.service.commons.authn.tokens.SecTokenManager;
import org.perfsonar.service.commons.authn.tokens.SecurityToken;
import org.perfsonar.service.commons.exceptions.PerfSONARException;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
public class AuthNRequestTest {
+
+ private void testRequest(DocumentBuilder builder, String
endPoint,String keyFile,String certFile,String saxParser) throws
PerfSONARException, IOException, SAXException {
+ Document request = builder.newDocument();
+ Message authnRequest = new
AuthNEERequestGenerator().generateRequestMessage();
+ request = authnRequest.getDOM(request);
+ // build a SOAPBodyElement from the document
+ SOAPBodyElement requestMessage =
+ new SOAPBodyElement(request.getDocumentElement());
+
+ AuthNData data=AuthNDataFactory.getDefaultAuthNData();
+ Object newRequest=data.addX509STInMessage(requestMessage, keyFile,
certFile);
+ SOAPEnvelope envelope = (SOAPEnvelope)newRequest;
+
+ try {
+
+ SecurityToken st=new SecurityToken(new SecTokenRawManager());
+ javax.xml.soap.SOAPHeader header=envelope.getHeader();
+ st.setSecToken(header);
+
+ AuthNRequest authnReq=new AuthNRequest(st);
+ AADispatchManager aadm=new AADispatchManager(new
AADispatchBasicSOAPProtocol(endPoint,saxParser));
+ AuthNResponse authnRes=aadm.getAuthentication(authnReq);
+
+ if (authnRes.getStatus()==AuthNResponse.AUTHENTICATED) {
+ System.out.println("Result: AUTHENTICATED!");
+ }
+ else {
+ System.out.println("Result: NOT AUTHENTICATED!");
+ }
+ System.out.println("Code Result: "+authnRes.getResultCode());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PerfSONARException("error.common.parse_error",
+ "Parse/validation error, " +
+ "Cannot convert request to Message. " +
+ "Nested error messsage was "+e.getMessage());
+
+ }
+ }
+
+ private void testRequestWithoutST(DocumentBuilder builder, String
endPoint,String saxParser) throws PerfSONARException, IOException,
SAXException {
+ Document request = builder.newDocument();
+ Message authnRequest = new
AuthNEERequestGenerator().generateRequestMessage();
+ request = authnRequest.getDOM(request);
+
+ // build a SOAPBodyElement from the document
+ SOAPBodyElement requestMessage =
+ new SOAPBodyElement(request.getDocumentElement());
+
+ SOAPEnvelope envelope = new SOAPEnvelope();
+ envelope.addBodyElement(requestMessage);
+
+ try {
+
+ SecurityToken st=new SecurityToken(new SecTokenRawManager());
+ javax.xml.soap.SOAPHeader header=envelope.getHeader();
+ st.setSecToken(header);
+
+ AuthNRequest authnReq=new AuthNRequest(st);
+ AADispatchManager aadm=new AADispatchManager(new
AADispatchBasicSOAPProtocol(endPoint,saxParser));
+ AuthNResponse authnRes=aadm.getAuthentication(authnReq);
+
+ if (authnRes.getStatus()==AuthNResponse.AUTHENTICATED) {
+ System.out.println("Result: AUTHENTICATED!");
+ }
+ else {
+ System.out.println("Result: NOT AUTHENTICATED!");
+ }
+ System.out.println("Code Result: "+authnRes.getResultCode());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PerfSONARException("error.common.parse_error",
+ "Parse/validation error, " +
+ "Cannot convert request to Message. " +
+ "Nested error messsage was "+e.getMessage());
+
+ }
+ }
+
@SuppressWarnings(value={"deprecation"})
public void makeRequest(String[] args) {
try {
String endPoint = null;
- String inputFile = null;
String keyFile = null;
String certFile = null;
String saxParser = null;
- if (args.length == 5) {
+ if (args.length == 4) {
endPoint = args[0];
- inputFile = args[1];
- keyFile = args[2];
- certFile = args[3];
- saxParser = args[4];
+ keyFile = args[1];
+ certFile = args[2];
+ saxParser = args[3];
} else {
System.out.println("Error: Wrong number ("+args.length+") of
parameters!!!");
return;
}
System.out.println("End point: " + endPoint);
- System.out.println("Request file: " + inputFile);
System.out.println("Private key file: " + keyFile);
System.out.println("Certificate file: " + certFile);
System.out.println("SAX parser: " + saxParser);
// read the request into a org.w3c.DOM.Document
- Document request = null;
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
-
DocumentBuilder builder = factory.newDocumentBuilder();
- request = builder.parse(new File(inputFile));
-
- // build a SOAPBodyElement from the document
- SOAPBodyElement requestMessage =
- new SOAPBodyElement(request.getDocumentElement());
-
- AuthNData data=AuthNDataFactory.getDefaultAuthNData();
- Object newRequest=data.addX509STInMessage(requestMessage,
keyFile, certFile);
- SOAPEnvelope envelope = (SOAPEnvelope)newRequest;
-
- try {
-
- SecurityToken st=new SecurityToken(new SecTokenRawManager());
- javax.xml.soap.SOAPHeader header=envelope.getHeader();
- st.setSecToken(header);
-
- AuthNRequest authnReq=new AuthNRequest(st);
- AADispatchManager aadm=new AADispatchManager(new
AADispatchBasicSOAPProtocol(endPoint,inputFile,saxParser));
- AuthNResponse authnRes=aadm.getAuthentication(authnReq);
- if (authnRes.getStatus()==AuthNResponse.AUTHENTICATED) {
- System.out.println("Result: AUTHENTICATED!");
- }
- else {
- System.out.println("Result: NOT AUTHENTICATED!");
- }
- System.out.println("Code Result: "+authnRes.getResultCode());
-
- } catch (Exception e) {
- e.printStackTrace();
- throw new PerfSONARException("error.common.parse_error",
- "Parse/validation error, " +
- "Cannot convert request to Message. " +
- "Nested error messsage was "+e.getMessage());
-
- }
+
+ System.out.println("##########################");
+ System.out.println("# Test #1: AuthN request #");
+ System.out.println("##########################");
+ testRequest(builder,endPoint,keyFile,certFile,saxParser);
+
System.out.println("#############################################");
+ System.out.println("# Test #2: AuthN request without a SecToken
#");
+
System.out.println("#############################################");
+ testRequestWithoutST(builder,endPoint,saxParser);
} catch(Exception e) {
System.err.println("AuthNRequestTest.makeRequest: General
exception encountered by client");
e.printStackTrace();
@@ -128,12 +183,10 @@
class AADispatchBasicSOAPProtocol implements AADispatchProtocol {
private String asPoint;
- private String fileAuthnRequest;
private String saxParser;
- public AADispatchBasicSOAPProtocol(String asPoint, String
fileAuthnRequest, String saxParser) throws PerfSONARException {
+ public AADispatchBasicSOAPProtocol(String asPoint, String saxParser)
throws PerfSONARException {
this.asPoint=asPoint;
- this.fileAuthnRequest=fileAuthnRequest;
this.saxParser=saxParser;
}
@@ -149,12 +202,18 @@
call.setOperationName(new
QName("http://soapinterop.org/","submit"));
// read the request into a org.w3c.DOM.Document
- Document request = null;
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder =
factory.newDocumentBuilder();
- request = builder.parse(new File(fileAuthnRequest));
+ Document request = builder.newDocument();
+ Message authnRequest = new
AuthNEERequestGenerator().generateRequestMessage();
+ request = authnRequest.getDOM(request);
+ Element parameter=null;
+ NodeList nodelist =
org.apache.xpath.XPathAPI.selectNodeList(request,
"//nmwg:parameter[@name='SecurityToken']");
+ if (nodelist.getLength()>0) {
+ parameter=(Element)nodelist.item(0);
+ }
// build a SOAPBodyElement from the document
SOAPBodyElement requestMessage =
@@ -165,6 +224,10 @@
Iterator<SOAPHeaderElement>
it=header.examineAllHeaderElements();
while (it.hasNext()) {
SOAPHeaderElement he=it.next();
+ NodeList nodelist2 =
org.apache.xpath.XPathAPI.selectNodeList(he, "//Assertion");
+ if (nodelist2.getLength()>0) {
+
parameter.setTextContent(AADispatchSOAPProtocol.WSS_SAML);
+ }
envelope.getHeader().addChildElement(he);
}
@@ -198,6 +261,10 @@
serial.serialize( result.getDocumentElement() );
outWriter.close();
+
+ System.out.println("---- Response message");
+ System.out.println(outWriter.toString());
+ System.out.println("---------------------");
Message responseNmwg =
org.perfsonar.commons.util.XMLUtils.convertToMessage(
result, saxParser);
Modified: trunk/perfsonar/src/org/perfsonar/service/web/RequestHandler.java
===================================================================
--- trunk/perfsonar/src/org/perfsonar/service/web/RequestHandler.java
2007-08-30 11:22:48 UTC (rev 2750)
+++ trunk/perfsonar/src/org/perfsonar/service/web/RequestHandler.java
2007-08-30 11:30:05 UTC (rev 2751)
@@ -146,7 +146,12 @@
}
// Check if it's needed authentication for this type of
message
- String
checkAuthNParam=configuration.getProperty(AuthNComponent.CHECK_AUTHN_PARAM);
+ String checkAuthNParam=null;
+ try {
+
checkAuthNParam=configuration.getProperty(AuthNComponent.CHECK_AUTHN_PARAM);
+ } catch (PerfSONARException e) {
+ checkAuthNParam=null;
+ }
if
(checkAuthNParam!=null&&checkAuthNParam.equals(AuthNComponent.YES_CHECK_AUTHN))
{
logger.debug(
"RequestHandler: " +
- perfsonar: r2751 - in trunk/perfsonar: ant ant/as conf doc doc/as schema/example-instances/perfSONAR/AS/test src/org/perfsonar/client/commons/authn src/org/perfsonar/client/commons/authn/edugain src/org/perfsonar/client/commons/authn/edugain/mds src/org/perfsonar/client/commons/authn/saslca src/org/perfsonar/client/commons/requests src/org/perfsonar/client/commons/requests/authService src/org/perfsonar/client/testHarness src/org/perfsonar/commons/auxiliary/components/authn/wssec src/org/perfsonar/commons/messages src/org/perfsonar/service/authService src/org/perfsonar/service/commons/authn src/org/perfsonar/service/commons/engine src/org/perfsonar/service/testHarness/authService src/org/perfsonar/service/web, svnlog, 08/30/2007
Archive powered by MHonArc 2.6.16.