GithubHelp home page GithubHelp logo

aaa4j / aaa4j-radius Goto Github PK

View Code? Open in Web Editor NEW
21.0 6.0 9.0 481 KB

Java library for building RADIUS clients and RADIUS servers

Home Page: https://aaa4j.org

License: Apache License 2.0

Java 100.00%
radius radius-protocol radius-client radius-server radius-proxy aaa

aaa4j-radius's Introduction

AAA4J-RADIUS

GitHub Maven Central GitHub Workflow Status (branch) GitHub Repo stars

Java library for building RADIUS clients and RADIUS servers.

Features

  • RADIUS client implementation
  • RADIUS server implementation
  • Standard RADIUS data types
  • Standard RADIUS dictionary
  • Custom dictionary support
  • FreeRADIUS dictionary support
  • Java 8+ support
  • Apache-2.0 license

Usage

Client

Add aaa4j-radius-client dependency from Maven Central:

<dependency>
    <groupId>org.aaa4j.radius</groupId>
    <artifactId>aaa4j-radius-client</artifactId>
    <version>0.3.0</version>
</dependency>

Build a RadiusClient using UdpRadiusClient.newBuilder() and send a request packet using send():

package org.aaa4j.radius.examples;

import org.aaa4j.radius.client.RadiusClient;
import org.aaa4j.radius.client.RadiusClientException;
import org.aaa4j.radius.client.clients.UdpRadiusClient;
import org.aaa4j.radius.core.attribute.StringData;
import org.aaa4j.radius.core.attribute.TextData;
import org.aaa4j.radius.core.attribute.attributes.NasIdentifier;
import org.aaa4j.radius.core.attribute.attributes.UserName;
import org.aaa4j.radius.core.attribute.attributes.UserPassword;
import org.aaa4j.radius.core.packet.Packet;
import org.aaa4j.radius.core.packet.packets.AccessAccept;
import org.aaa4j.radius.core.packet.packets.AccessRequest;

import java.net.InetSocketAddress;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

    public static void main(String[] args) {
        RadiusClient radiusClient = UdpRadiusClient.newBuilder()
                .secret("sharedsecret".getBytes(UTF_8))
                .address(new InetSocketAddress("10.1.1.10", 1812))
                .build();

        AccessRequest accessRequest = new AccessRequest(List.of(
                new UserName(new TextData("john.doe")),
                new UserPassword(new StringData("hunter2".getBytes(UTF_8))),
                new NasIdentifier(new TextData("SSID1"))
        ));

        try {
            Packet responsePacket = radiusClient.send(accessRequest);

            if (responsePacket instanceof AccessAccept) {
                System.out.println("Accepted");
            }
            else {
                System.out.println("Rejected");
            }
        }
        catch (RadiusClientException e) {
            e.printStackTrace();
        }
    }

}

Server

Add aaa4j-radius-server dependency from Maven Central:

<dependency>
    <groupId>org.aaa4j.radius</groupId>
    <artifactId>aaa4j-radius-server</artifactId>
    <version>0.3.0</version>
</dependency>

Implement RadiusServer.Handler to handle RADIUS clients and packets, build a RadiusServer using UdpRadiusServer.newBuilder(), and start the server using start():

package org.aaa4j.radius.examples;

import org.aaa4j.radius.core.attribute.attributes.UserName;
import org.aaa4j.radius.core.attribute.attributes.UserPassword;
import org.aaa4j.radius.core.packet.Packet;
import org.aaa4j.radius.core.packet.packets.AccessAccept;
import org.aaa4j.radius.core.packet.packets.AccessReject;
import org.aaa4j.radius.core.packet.packets.AccessRequest;
import org.aaa4j.radius.server.RadiusServer;
import org.aaa4j.radius.server.servers.UdpRadiusServer;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

    public static void main(String[] args) throws Exception {
        RadiusServer radiusServer = UdpRadiusServer.newBuilder()
                .bindAddress(new InetSocketAddress(1812))
                .handler(new RadiusHandler())
                .build();

        radiusServer.start();
    }

    private static class RadiusHandler implements RadiusServer.Handler {

        @Override
        public byte[] handleClient(InetAddress clientAddress) {
            if (clientAddress.getHostAddress().equals("10.5.5.50")) {
                return "sharedsecret".getBytes(UTF_8);
            }

            return null;
        }

        @Override
        public Packet handlePacket(InetAddress clientAddress, Packet requestPacket) {
            if (requestPacket instanceof AccessRequest) {
                Optional<UserName> userNameAttribute = requestPacket.getAttribute(UserName.class);
                Optional<UserPassword> userPasswordAttribute = requestPacket.getAttribute(UserPassword.class);

                if (userNameAttribute.isPresent() && userPasswordAttribute.isPresent()) {
                    String username = userNameAttribute.get().getData().getValue();
                    String password = new String(userPasswordAttribute.get().getData().getValue(), UTF_8);

                    if (username.equals("john.doe") && password.equals("hunter2")) {
                        return new AccessAccept();
                    }
                }

                return new AccessReject();
            }

            return null;
        }

    }

}

License

Copyright 2020 The AAA4J-RADIUS Authors

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

aaa4j-radius's People

Contributors

tsyd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aaa4j-radius's Issues

Request Authenticator does not seem to be correctly implemented for RFC 2866 (Accounting)

Hi Thomas,

Request Authenticator seems to be implemented correctly for Access-Request, according to RFC 2865 the value MUST be changed each time a new Identifier is used. I think this is sufficiently covered by

byte[] authenticatorBytes = new byte[16];
randomProvider.nextBytes(authenticatorBytes);

but according to RFC 2866, the Request Authenticator for Accounting-Request shall contain a 16-octet MD5 hash value calculated according to the method described in "Request Authenticator" above (RFC 2866).

I used your package to write a high throughput / high parallel test application to test a new configuration of our radius server (not your package). Thank you so much btw for this awesome package. I needed to adapt org.aaa4j.radius.core.packet.PacketCodec#encodeRequest for our radius server to accept "your" accounting requests. I just added this dirty piece of code to the end of the method, and that did the trick:

        if (request instanceof AccountingRequest) {
            Arrays.fill(bytes, 4, 4 + 16, (byte) 0x00);

            MessageDigest md5Instance = getMd5Instance();
            md5Instance.update(bytes);
            md5Instance.update(secret);
            byte[] sign = md5Instance.digest();

            System.arraycopy(sign, 0, bytes, 4, 16);
        }

I know this is dirty and kinda ugly, and I basically just disabled all unit test for now :). Currently I'm only using a tiny fraction of your code, just to generate Access-Requests, parse Access-Responses and generating Accounting-Requests. If I find the time, I will create a fork and make a contribution incl. unit tests, but right now I just wanted to let you know, in case you find the time yourself.

Thanks again for this package, it saved so much of my time.

Java version

Hi,
Could you please let me know, aaa4j-radius client will work for java 6 version?
I am our application, we are using java 6 version.
could you please let me know, is it will work for java 6 version?

Support CHAP?

Is chap supported? I do not find how to send a chap auth request.

Setting timeout

Hi,

I wonder, how can I set a value for xx seconds timeout for a client/request?

Calrification

  1. How do i get the Reason Code and Reason attributes
  2. how do i get the event ids
  3. While i am passing username and password
    reason of failures:
    1) Username disabled
    2) Wrong password
    Reason message
    Which attribute, we have to get the reason of failures
    While i am passing username, token and state
    3) Wrong token
    4) State invalid or expiry.
    Could you please help me on this

UserPasswordDataCodec.encode shortens Password to 16 bytes instead of padding to multiple.

Hi Thomas,

I think your encode method for the password org.aaa4j.radius.core.attribute.UserPasswordDataCodec#encode makes a small math mistake. Your line is

Math.min(16, password.length + ((16 - password.length) % 16))

This line will always return 16. I think the min might be meant as a max (then it would work in Python), and then Java does not deal with negative values and modulo the same, as e.g. Python.

//Java
(16 - 19) % 16 = -3
#Python
>>> (16 - 19) % 16
13
>>> min(16,19 + ((16 - 19) % 16))
16
>>> max(16,19 + ((16 - 19) % 16))
32

In Java I think you need:

byte[] paddedPassword = new byte[password.length - ((password.length - 1) % 16) + 15];

Again, if I find the time, I will make this part of my contribution.

For completeness, the exception when using a 19 byte password was:

java.lang.ArrayIndexOutOfBoundsException: arraycopy: last destination index 19 out of bounds for byte[16]

	at java.base/java.lang.System.arraycopy(Native Method)
	at org.aaa4j.radius.core.attribute.UserPasswordDataCodec.encode(UserPasswordDataCodec.java:88)
	at org.aaa4j.radius.core.attribute.StandardAttribute$Codec.encode(StandardAttribute.java:91)
	at org.aaa4j.radius.core.packet.PacketCodec.encodeAttributes(PacketCodec.java:519)
	at org.aaa4j.radius.core.packet.PacketCodec.encodeRequest(PacketCodec.java:123)
	at org.aaa4j.radius.client.clients.UdpRadiusClient.send(UdpRadiusClient.java:104)
	at de.biotronik.pet.tools.crm.server.backend.RadiusClientService.authenticate(RadiusClientService.java:110)
	at RadiusIntegrationTest.testRadiusServer(RadiusIntegrationTest.java:50)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

King Regards.

Uncaught server error: java.lang.NoClassDefFoundError: org/aaa4j/radius/client/RetransmissionStrategy

Hi,

I wonder why I am getting this error in runtime after importing the package to maven as described on the README page:

Uncaught server error: java.lang.NoClassDefFoundError: org/aaa4j/radius/client/RetransmissionStrategy

The class is indeed imported to the client, and it works when I am not using it on my Maven project, but when importing the package to my Maven project, it doesn't find this specific class.

I have it like this on my project:

     import org.aaa4j.radius.client.IntervalRetransmissionStrategy;
     import org.aaa4j.radius.client.RetransmissionStrategy;

               this.radiusClient = UdpRadiusClient.newBuilder()
                    .secret(secret.getBytes(UTF_8))
                    .address(new InetSocketAddress(host, 1812))
                    .retransmissionStrategy(new IntervalRetransmissionStrategy(1, Duration.ofSeconds(timeout)))
                    .build();

Can you help me?

Best,
Francis

the vendorspecificatrribues problem

Hello, can you solve the search and insertion of multiple private vendor attributes with the following data structure
[typeid,vendorid] //typeid = 26, or24x.26
[vendortype,length,value]
[vendortype,length,value]
[vendortype,length,value]
[vendortype,length,value]
[vendortype,length,value]
I spent a long time solving the parsing problem, but I couldn't solve the insertion problem of the above structure. If I try to solve it forcefully, it will turn the code into a pile of crap
thinks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.