/* * Copyright 2011 Future Systems * * 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. */ package org.krakenapps.radius.client.auth; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import org.krakenapps.radius.client.MalformedResponseException; import org.krakenapps.radius.client.RadiusClient; import org.krakenapps.radius.protocol.AccessRequest; import org.krakenapps.radius.protocol.ChapPasswordAttribute; import org.krakenapps.radius.protocol.RadiusPacket; import org.krakenapps.radius.protocol.RadiusResponse; import org.krakenapps.radius.protocol.UserNameAttribute; public class ChapAuthenticator implements Authenticator { private RadiusClient client; private String userName; private String password; public ChapAuthenticator(RadiusClient client, String userName, String password) { this.client = client; this.userName = userName; this.password = password; } @Override public RadiusResponse authenticate() throws IOException { String sharedSecret = client.getSharedSecret(); byte chapIdent = (byte) 0xd2; byte[] h = null; AccessRequest req = new AccessRequest(); // calculate hash = MD5(chap ident + password + nonce) try { MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(chapIdent); md5.update(password.getBytes()); md5.update(req.getAuthenticator()); h = md5.digest(); } catch (NoSuchAlgorithmException e) { throw new IOException(e); } // build chap request req.setIdentifier(client.getNextId()); req.setUserName(new UserNameAttribute(userName)); req.setChapPassword(new ChapPasswordAttribute(chapIdent, h)); req.finalize(); // send request DatagramSocket socket = new DatagramSocket(); try { socket.connect(client.getIpAddress(), client.getPort()); byte[] payload = req.getBytes(); DatagramPacket packet = new DatagramPacket(payload, payload.length); socket.setSoTimeout(5000); socket.send(packet); // receive chap response byte[] buf = new byte[65535]; DatagramPacket response = new DatagramPacket(buf, buf.length); socket.receive(response); RadiusResponse resp = (RadiusResponse) RadiusPacket.parse(sharedSecret, buf); byte[] expectedAuthenticator = RadiusResponse.calculateResponseAuthenticator(resp, sharedSecret, req.getAuthenticator()); if (!Arrays.equals(expectedAuthenticator, resp.getAuthenticator())) throw new MalformedResponseException(req, resp); return resp; } finally { socket.close(); } } }