/** * JRadius - A RADIUS Server Java Adapter * Copyright (c) 2009 Coova Technologies, LLC <support@coova.com> * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package net.jradius.radsec; import java.io.DataInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.ByteOrder; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import net.jradius.client.RadiusClientTransport; import net.jradius.exception.RadiusException; import net.jradius.packet.AccountingRequest; import net.jradius.packet.PacketFactory; import net.jradius.packet.RadiusFormat; import net.jradius.packet.RadiusRequest; import net.jradius.packet.RadiusResponse; public class RadSecClientTransport extends RadiusClientTransport { private SSLSocket socket; private SSLSocket socketAcct; private KeyManager keyManagers[]; private TrustManager trustManagers[]; protected final ByteBuffer buffer_in; protected final ByteBuffer buffer_out; private String[] protocols = new String[] { "TLSv1" }; public RadSecClientTransport(KeyManager keyManager, TrustManager trustManager) { this(new KeyManager[] { keyManager } , new TrustManager[] { trustManager }); } public RadSecClientTransport(KeyManager keyManagers[], TrustManager trustManagers[]) { this.keyManagers = keyManagers; this.trustManagers = trustManagers; buffer_in = ByteBuffer.allocate(25000); buffer_in.order(ByteOrder.BIG_ENDIAN); buffer_out = ByteBuffer.allocate(25000); buffer_out.order(ByteOrder.BIG_ENDIAN); } private void initialize() { try { SSLContext sslContext = SSLContext.getInstance(protocols[0]); sslContext.init(keyManagers, trustManagers, null); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); socket = (SSLSocket) socketFactory.createSocket(getRemoteInetAddress(), getAuthPort()); socket.setReuseAddress(true); socket.setSoTimeout(getSocketTimeout() * 1000); socket.setEnabledProtocols(protocols); if (getAcctPort() != getAuthPort()) { socketAcct = (SSLSocket) socketFactory.createSocket(getRemoteInetAddress(), getAcctPort()); socketAcct.setReuseAddress(true); socketAcct.setSoTimeout(getSocketTimeout() * 1000); socketAcct.setEnabledProtocols(protocols); } } catch (Exception e) { e.printStackTrace(); } } public RadiusResponse sendReceive(RadiusRequest p, int retries) throws RadiusException { if (socket == null) initialize(); return super.sendReceive(p, retries); } public void close() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } protected RadiusResponse receive(RadiusRequest req) throws Exception { RadiusResponse res = null; DataInputStream in = new DataInputStream(socket.getInputStream()); synchronized (in) { if (statusListener != null) statusListener.onBeforeReceive(this); int code = RadiusFormat.readUnsignedByte(in); int identifier = RadiusFormat.readUnsignedByte(in); int length = RadiusFormat.readUnsignedShort(in); buffer_in.clear(); buffer_in.limit(in.read(buffer_in.array(), 0, length)); res = (RadiusResponse) PacketFactory.parseUDP(code, identifier, length, buffer_in, false); if (statusListener != null) statusListener.onAfterReceive(this, res); } return res; } @Override protected void send(RadiusRequest req, int attempt) throws Exception { Socket sock = socket; if (socketAcct != null && req instanceof AccountingRequest) sock = socketAcct; RadiusFormat format = RadiusFormat.getInstance(); OutputStream out = sock.getOutputStream(); buffer_out.clear(); format.packPacket(req, "radsec", buffer_out, true); synchronized (out) { if (statusListener != null) statusListener.onBeforeSend(this, req); out.write(buffer_out.array(), 0, buffer_out.position()); if (statusListener != null) statusListener.onAfterSend(this); } } }