Search in sources :

Example 1 with RADIUSAttribute

use of org.onlab.packet.RADIUSAttribute in project aaa by opencord.

the class AaaManager method checkResponseMessageAuthenticator.

private boolean checkResponseMessageAuthenticator(String key, RADIUS radiusPacket, byte[] requestAuthenticator) {
    byte[] newHash = new byte[16];
    Arrays.fill(newHash, (byte) 0);
    // looking for the attributes - exit if there are no such attributes
    if (radiusPacket.getAttributeList(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH).isEmpty()) {
        log.warn("Empty Attribute List for packet {} with identifier {}", radiusPacket, radiusPacket.getIdentifier());
        return false;
    }
    // get the attribute - further verify if it is null or not (not really needed)
    RADIUSAttribute attribute = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH);
    if (attribute == null) {
        log.warn("Null Message Authenticator for packet {} with identifier {}", radiusPacket, radiusPacket.getIdentifier());
        return false;
    }
    byte[] messageAuthenticator = attribute.getValue();
    byte[] authenticator = radiusPacket.getAuthenticator();
    radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, newHash);
    radiusPacket.setAuthenticator(requestAuthenticator);
    // Calculate the MD5 HMAC based on the message
    try {
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5");
        Mac mac = Mac.getInstance("HmacMD5");
        mac.init(keySpec);
        newHash = mac.doFinal(radiusPacket.serialize());
    } catch (Exception e) {
        log.error("Failed to generate message authenticator: {}", e.getMessage());
    }
    radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuthenticator);
    radiusPacket.setAuthenticator(authenticator);
    // Compare the calculated Message-Authenticator with the one in the message
    return Arrays.equals(newHash, messageAuthenticator);
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) RADIUSAttribute(org.onlab.packet.RADIUSAttribute) Mac(javax.crypto.Mac) DeserializationException(org.onlab.packet.DeserializationException) UnknownHostException(java.net.UnknownHostException)

Example 2 with RADIUSAttribute

use of org.onlab.packet.RADIUSAttribute in project aaa by opencord.

the class AaaManager method handleRadiusPacket.

/**
 * Handles RADIUS packets.
 *
 * @param radiusPacket RADIUS packet coming from the RADIUS server.
 */
public void handleRadiusPacket(RADIUS radiusPacket) {
    if (log.isTraceEnabled()) {
        log.trace("Received RADIUS packet {} with identifier {}", radiusPacket, radiusPacket.getIdentifier() & 0xff);
    }
    if (radiusOperationalStatusService.isRadiusResponseForOperationalStatus(radiusPacket.getIdentifier())) {
        if (log.isTraceEnabled()) {
            log.trace("Handling operational status RADIUS packet {} with identifier {}", radiusPacket, radiusPacket.getIdentifier() & 0xff);
        }
        radiusOperationalStatusService.handleRadiusPacketForOperationalStatus(radiusPacket);
        return;
    }
    if (log.isTraceEnabled()) {
        log.trace("Handling actual RADIUS packet for supplicant {} with identifier {}", radiusPacket, radiusPacket.getIdentifier() & 0xff);
    }
    RequestIdentifier identifier = RequestIdentifier.of(radiusPacket.getIdentifier());
    String sessionId = idManager.getSessionId(identifier);
    if (sessionId == null) {
        log.error("Invalid packet identifier {}, could not find corresponding " + "state machine ... exiting", radiusPacket.getIdentifier());
        aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
        aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
        return;
    }
    idManager.releaseIdentifier(identifier);
    StateMachine stateMachine = stateMachines.get(sessionId);
    if (stateMachine == null) {
        log.error("Invalid packet identifier {}, could not find corresponding " + "state machine ... exiting", radiusPacket.getIdentifier());
        aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
        aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
        return;
    }
    // instance of StateMachine using the sessionId for updating machine stats
    StateMachine machineStats = stateMachines.get(stateMachine.sessionId());
    EAP eapPayload;
    Ethernet eth;
    checkReceivedPacketForValidValidator(radiusPacket, stateMachine.requestAuthenticator());
    // increasing packets and octets received from server
    machineStats.incrementTotalPacketsReceived();
    try {
        machineStats.incrementTotalOctetReceived(radiusPacket.decapsulateMessage().getLength());
    } catch (DeserializationException e) {
        log.error(e.getMessage());
        return;
    }
    if (outPacketSet.contains(radiusPacket.getIdentifier())) {
        aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(false);
        outPacketSet.remove(new Byte(radiusPacket.getIdentifier()));
    }
    MacAddress dstMac = stateMachine.supplicantAddress();
    ConnectPoint supplicantCp = stateMachine.supplicantConnectpoint();
    switch(radiusPacket.getCode()) {
        case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
            log.debug("RADIUS packet: RADIUS_CODE_ACCESS_CHALLENGE for dev/port: {}/{} " + "with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
            byte[] challengeState = null;
            if (radiusAttrState != null) {
                challengeState = radiusAttrState.getValue();
            }
            try {
                eapPayload = radiusPacket.decapsulateMessage();
                eth = buildEapolResponse(stateMachine.supplicantAddress(), MacAddress.valueOf(nasMacAddress), stateMachine.vlanId(), EAPOL.EAPOL_PACKET, eapPayload, stateMachine.priorityCode());
                stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
            } catch (DeserializationException e) {
                log.error(e.getMessage());
                break;
            }
            log.debug("Send EAP challenge response to supplicant on dev/port: {}/{}" + " with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), true);
            aaaStatisticsManager.getAaaStats().increaseChallengeResponsesRx();
            outPacketSupp.add(eapPayload.getIdentifier());
            aaaStatisticsManager.getAaaStats().incrementPendingReqSupp();
            // increasing packets send to server
            machineStats.incrementTotalPacketsSent();
            machineStats.incrementTotalOctetSent(eapPayload.getLength());
            break;
        case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
            log.debug("RADIUS packet: RADIUS_CODE_ACCESS_ACCEPT for dev/port: {}/{}" + " with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            // send an EAPOL - Success to the supplicant.
            byte[] eapMessageSuccess = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
            try {
                eapPayload = EAP.deserializer().deserialize(eapMessageSuccess, 0, eapMessageSuccess.length);
            } catch (DeserializationException e) {
                log.error(e.getMessage());
                break;
            }
            eth = buildEapolResponse(stateMachine.supplicantAddress(), MacAddress.valueOf(nasMacAddress), stateMachine.vlanId(), EAPOL.EAPOL_PACKET, eapPayload, stateMachine.priorityCode());
            log.info("Send EAP success message to supplicant on dev/port: {}/{}" + " with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), false);
            aaaStatisticsManager.getAaaStats().incrementEapolAuthSuccessTrans();
            stateMachine.authorizeAccess();
            aaaStatisticsManager.getAaaStats().increaseAcceptResponsesRx();
            // increasing packets send to server
            machineStats.incrementTotalPacketsSent();
            machineStats.incrementTotalOctetSent(eapPayload.getLength());
            break;
        case RADIUS.RADIUS_CODE_ACCESS_REJECT:
            log.debug("RADIUS packet: RADIUS_CODE_ACCESS_REJECT for dev/port: {}/{}" + " with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            // send an EAPOL - Failure to the supplicant.
            byte[] eapMessageFailure;
            eapPayload = new EAP();
            RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
            if (radiusAttrEap == null) {
                eapPayload.setCode(EAP.FAILURE);
                eapPayload.setIdentifier(stateMachine.challengeIdentifier());
                eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
            } else {
                eapMessageFailure = radiusAttrEap.getValue();
                try {
                    eapPayload = EAP.deserializer().deserialize(eapMessageFailure, 0, eapMessageFailure.length);
                } catch (DeserializationException e) {
                    log.error(e.getMessage());
                    break;
                }
            }
            eth = buildEapolResponse(stateMachine.supplicantAddress(), MacAddress.valueOf(nasMacAddress), stateMachine.vlanId(), EAPOL.EAPOL_PACKET, eapPayload, stateMachine.priorityCode());
            log.warn("Send EAP failure message to supplicant on dev/port: {}/{}" + " with MacAddress {} and Identifier {}", supplicantCp.deviceId(), supplicantCp.port(), dstMac, stateMachine.challengeIdentifier() & 0xff);
            sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), false);
            aaaStatisticsManager.getAaaStats().incrementEapolauthFailureTrans();
            stateMachine.denyAccess();
            aaaStatisticsManager.getAaaStats().increaseRejectResponsesRx();
            // increasing packets send to server
            machineStats.incrementTotalPacketsSent();
            machineStats.incrementTotalOctetSent(eapPayload.getLength());
            // pushing machine stats to kafka
            AaaSupplicantMachineStats machineObj = aaaSupplicantStatsManager.getSupplicantStats(machineStats);
            aaaSupplicantStatsManager.getMachineStatsDelegate().notify(new AaaMachineStatisticsEvent(AaaMachineStatisticsEvent.Type.STATS_UPDATE, machineObj));
            break;
        default:
            log.warn("Unknown RADIUS message received with code: {} for dev/port: {}/{}" + " with MacAddress {} and Identifier {}", radiusPacket.getCode(), supplicantCp.deviceId(), supplicantCp.port(), dstMac, radiusPacket.getIdentifier() & 0xff);
            aaaStatisticsManager.getAaaStats().increaseUnknownTypeRx();
            // increasing packets received to server
            machineStats.incrementTotalPacketsReceived();
            try {
                machineStats.incrementTotalOctetReceived(radiusPacket.decapsulateMessage().getLength());
            } catch (DeserializationException e) {
                log.error(e.getMessage());
                break;
            }
    }
    aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
}
Also used : AaaMachineStatisticsEvent(org.opencord.aaa.AaaMachineStatisticsEvent) MacAddress(org.onlab.packet.MacAddress) RADIUSAttribute(org.onlab.packet.RADIUSAttribute) ConnectPoint(org.onosproject.net.ConnectPoint) DeserializationException(org.onlab.packet.DeserializationException) EAP(org.onlab.packet.EAP) Ethernet(org.onlab.packet.Ethernet) AaaSupplicantMachineStats(org.opencord.aaa.AaaSupplicantMachineStats)

Aggregations

DeserializationException (org.onlab.packet.DeserializationException)2 RADIUSAttribute (org.onlab.packet.RADIUSAttribute)2 UnknownHostException (java.net.UnknownHostException)1 Mac (javax.crypto.Mac)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 EAP (org.onlab.packet.EAP)1 Ethernet (org.onlab.packet.Ethernet)1 MacAddress (org.onlab.packet.MacAddress)1 ConnectPoint (org.onosproject.net.ConnectPoint)1 AaaMachineStatisticsEvent (org.opencord.aaa.AaaMachineStatisticsEvent)1 AaaSupplicantMachineStats (org.opencord.aaa.AaaSupplicantMachineStats)1