/* * GetChannelAuthenticationCapabilities.java * Created on 2011-07-21 * * Copyright (c) Verax Systems 2011. * All rights reserved. * * This software is furnished under a license. Use, duplication, * disclosure and all other uses are restricted to the rights * specified in the written license agreement. */ package com.veraxsystems.vxipmi.coding.commands.session; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import com.veraxsystems.vxipmi.coding.commands.CommandCodes; import com.veraxsystems.vxipmi.coding.commands.IpmiCommandCoder; import com.veraxsystems.vxipmi.coding.commands.IpmiVersion; import com.veraxsystems.vxipmi.coding.commands.PrivilegeLevel; import com.veraxsystems.vxipmi.coding.commands.ResponseData; import com.veraxsystems.vxipmi.coding.payload.CompletionCode; import com.veraxsystems.vxipmi.coding.payload.IpmiPayload; import com.veraxsystems.vxipmi.coding.payload.lan.IPMIException; import com.veraxsystems.vxipmi.coding.payload.lan.IpmiLanRequest; import com.veraxsystems.vxipmi.coding.payload.lan.IpmiLanResponse; import com.veraxsystems.vxipmi.coding.payload.lan.NetworkFunction; import com.veraxsystems.vxipmi.coding.protocol.AuthenticationType; import com.veraxsystems.vxipmi.coding.protocol.IpmiMessage; import com.veraxsystems.vxipmi.coding.protocol.Ipmiv15Message; import com.veraxsystems.vxipmi.coding.security.CipherSuite; import com.veraxsystems.vxipmi.common.TypeConverter; /** * Wrapper for Get Channel Authentication Capabilities request */ public class GetChannelAuthenticationCapabilities extends IpmiCommandCoder { private PrivilegeLevel requestedPrivilegeLevel; private byte channelNumber; private IpmiVersion requestVersion; public void setRequestedPrivilegeLevel( PrivilegeLevel requestedPrivilegeLevel) { this.requestedPrivilegeLevel = requestedPrivilegeLevel; } public PrivilegeLevel getRequestedPrivilegeLevel() { return requestedPrivilegeLevel; } /** * Sets the channel number that will be put into IPMI command. * * @param channelNumber * - must be 0h-Bh or Eh-Fh
* Eh = retrieve information for channel this request was issued * on * @throws IllegalArgumentException */ public void setChannelNumber(int channelNumber) throws IllegalArgumentException { if (channelNumber < 0 || channelNumber > 0xF || channelNumber == 0xC || channelNumber == 0xD) { throw new IllegalArgumentException("Invalid channel number"); } this.channelNumber = TypeConverter.intToByte(channelNumber); } public int getChannelNumber() { return TypeConverter.byteToInt(channelNumber); } protected void setRequestVersion(IpmiVersion requestVersion) { this.requestVersion = requestVersion; } protected IpmiVersion getRequestVersion() { return requestVersion; } /** * Initiates class for decoding in 1.5 version. Sets requested privilege * level to user. Sets channel number to 14 indicating that response will * contain information for channel this request was issued on. Sets session * parameters to default. * * @see IpmiCommandCoder#setSessionParameters(IpmiVersion, CipherSuite, * AuthenticationType) * @see IpmiVersion */ public GetChannelAuthenticationCapabilities() { super(); setRequestedPrivilegeLevel(PrivilegeLevel.User); setChannelNumber(14); } /** * Initiates class. Sets IPMI version to version. Sets requested privilege * level to user. Sets channel number to 14 indicating that response will * contain information for channel this request was issued on. * * @param version * - Version of IPMI protocol used * @param requestVersion * - If Get Channel Authentication Capabilities command is sent * to BMC with requestVersion = {@link IpmiVersion#V15} it will * respond, that it does not support IPMI v2.0 even if it does. * @param cipherSuite * - {@link CipherSuite} containing authentication, * confidentiality and integrity algorithms for this session. * @see IpmiVersion */ public GetChannelAuthenticationCapabilities(IpmiVersion version, IpmiVersion requestVersion, CipherSuite cipherSuite) { super(version, cipherSuite, AuthenticationType.None); this.setRequestVersion(requestVersion); setRequestedPrivilegeLevel(PrivilegeLevel.User); setChannelNumber(14); } /** * Initiates class. Sets IPMI version to version. Sets requested privilege * level privilegeLevel. Sets channel number to channelNumber. * * @param version * - Version of IPMI protocol used * @param requestVersion * - If Get Channel Authentication Capabilities command is sent * to BMC with requestVersion = {@link IpmiVersion#V15} it will * respond, that it does not support IPMI v2.0 even if it does. * @param cipherSuite * - {@link CipherSuite} containing authentication, * confidentiality and integrity algorithms for this session. * @param privilegeLevel * - Maximum requested privilege level. Can't be * {@link PrivilegeLevel#MaximumAvailable}. * @param channelNumber * - must be 0h-Bh or Eh-Fh
* Eh = retrieve information for channel this request was issued * on. * @see IpmiVersion * @see PrivilegeLevel */ public GetChannelAuthenticationCapabilities(IpmiVersion version, IpmiVersion requestVersion, CipherSuite cipherSuite, PrivilegeLevel privilegeLevel, byte channelNumber) { super(version, cipherSuite, AuthenticationType.None); this.setRequestVersion(requestVersion); setRequestedPrivilegeLevel(privilegeLevel); setChannelNumber(channelNumber); } @Override public IpmiMessage encodeCommand(int sequenceNumber, int sessionId) throws InvalidKeyException, NoSuchAlgorithmException { if (getIpmiVersion() == IpmiVersion.V15) { if (sessionId != 0) { throw new IllegalArgumentException("Session ID must be 0"); } Ipmiv15Message message = new Ipmiv15Message(); message.setAuthenticationType(getAuthenticationType()); message.setSessionSequenceNumber(0); message.setSessionID(0); message.setPayload(preparePayload(sequenceNumber)); return message; } else { setAuthenticationType(AuthenticationType.RMCPPlus); return super.encodeCommand(sequenceNumber, sessionId); } } @Override protected IpmiPayload preparePayload(int sequenceNumber) { byte[] payload = new byte[2]; // payload[0] = TypeConverter.intToByte(sequenceNumber % 256); payload[0] = 0; if (getRequestVersion() == IpmiVersion.V20) { payload[0] |= TypeConverter.intToByte(0x80); } payload[0] |= channelNumber; payload[1] = encodePrivilegeLevel(requestedPrivilegeLevel); return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), payload, TypeConverter.intToByte(sequenceNumber % 64)); // return payload; } @Override public byte getCommandCode() { return CommandCodes.GET_CHANNEL_AUTHENTICATION_CAPABILITIES; } @Override public NetworkFunction getNetworkFunction() { return NetworkFunction.ApplicationRequest; } @Override public ResponseData getResponseData(IpmiMessage message) throws IllegalArgumentException, IPMIException { if (!isCommandResponse(message)) { throw new IllegalArgumentException( "This is not a response for Get Channel Authentication Capabilities command"); } if (!(message.getPayload() instanceof IpmiLanResponse)) { throw new IllegalArgumentException("Invalid response payload"); } if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { throw new IPMIException( ((IpmiLanResponse) message.getPayload()) .getCompletionCode()); } GetChannelAuthenticationCapabilitiesResponseData responseData = new GetChannelAuthenticationCapabilitiesResponseData(); byte[] raw = message.getPayload().getIpmiCommandData(); if (raw.length != 8) { throw new IllegalArgumentException("Data has invalid length"); } responseData.setChannelNumber(raw[0]); responseData.setIpmiv20Support(!((raw[1] & 0x80) == 0)); responseData .setAuthenticationTypes(new ArrayList()); if ((raw[1] & 0x20) != 0) { responseData.getAuthenticationTypes().add(AuthenticationType.Oem); } if ((raw[1] & 0x10) != 0) { responseData.getAuthenticationTypes() .add(AuthenticationType.Simple); } if ((raw[1] & 0x04) != 0) { responseData.getAuthenticationTypes().add(AuthenticationType.Md5); } if ((raw[1] & 0x02) != 0) { responseData.getAuthenticationTypes().add(AuthenticationType.Md2); } if ((raw[1] & 0x01) != 0) { responseData.getAuthenticationTypes().add(AuthenticationType.None); } responseData.setKgEnabled(!((raw[2] & 0x20) == 0)); responseData.setPerMessageAuthenticationEnabled((raw[2] & 0x10) == 0); responseData.setUserLevelAuthenticationEnabled((raw[2] & 0x08) == 0); responseData.setNonNullUsernamesEnabled(!((raw[2] & 0x04) == 0)); responseData.setNullUsernamesEnabled(!((raw[2] & 0x02) == 0)); responseData.setAnonymusLoginEnabled(!((raw[2] & 0x01) == 0)); byte[] oemId = new byte[4]; System.arraycopy(raw, 4, oemId, 0, 3); oemId[3] = 0; responseData.setOemId(TypeConverter.littleEndianByteArrayToInt(oemId)); responseData.setOemData(raw[7]); return responseData; } /** * Sets session parameters. * * @param version * - IPMI version of the command. * @param cipherSuite * - {@link CipherSuite} containing authentication, * confidentiality and integrity algorithms for this session. * @param authenticationType * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. */ @Override public void setSessionParameters(IpmiVersion version, CipherSuite cipherSuite, AuthenticationType authenticationType) { if (version == IpmiVersion.V20 && authenticationType != AuthenticationType.RMCPPlus && authenticationType != AuthenticationType.None) { throw new IllegalArgumentException( "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); } setIpmiVersion(version); setAuthenticationType(authenticationType); setCipherSuite(cipherSuite); } }