##
## 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.
##

Releases
--------

The current release is ${release_version} and was published on ${release_date}. The release note for this
release can be found [here](release-notes/${release_version}.html).

The following distributions are available for download:

&nbsp;              | Link                                         | Checksums and signatures
--------------------|----------------------------------------------|-------------------------
Binary distribution | [rampart-dist-${release_version}-bin.zip][1] | [SHA512][3] [PGP][4]
Source distribution | [rampart-dist-${release_version}-src.zip][5] | [SHA512][7] [PGP][8]

The binary distribution contains the following Axis2 modules:

*   `rampart-${release_version}.mar` provides support for WS-Security and WS-SecureConversation
    features.

*   `rahas-${release_version}.mar` provides the necessary components to enable SecurityTokenService
    functionality on a service.

The signatures of the distributions can be [verified][9] against the public keys in the [KEYS][10] file.

Maintenance releases from branches other than the main branch can be found [here][11].
Distributions for older releases can be found in the [archive][12].

All releases are also available as Maven artifacts in the [central repository][13].

[1]: http://www.apache.org/dyn/closer.lua/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-bin.zip
[3]: https://www.apache.org/dist/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-bin.zip.sha512
[4]: https://www.apache.org/dist/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-bin.zip.asc
[5]: http://www.apache.org/dyn/closer.lua/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-src.zip
[7]: https://www.apache.org/dist/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-src.zip.sha512
[8]: https://www.apache.org/dist/axis/axis2/java/rampart/${release_version}/rampart-dist-${release_version}-src.zip.asc
[9]: http://www.apache.org/dev/release-signing#verifying-signature
[10]: https://www.apache.org/dist/axis/axis2/java/rampart/KEYS
[11]: http://www.apache.org/dyn/closer.lua/axis/axis2/java/rampart/
[12]: http://archive.apache.org/dist/axis/axis2/java/rampart/
[13]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.rampart%22
