1 package org.metricshub.ipmi.core.coding.commands.session;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.metricshub.ipmi.core.coding.commands.CommandCodes;
26 import org.metricshub.ipmi.core.coding.commands.IpmiCommandCoder;
27 import org.metricshub.ipmi.core.coding.commands.IpmiVersion;
28 import org.metricshub.ipmi.core.coding.commands.PrivilegeLevel;
29 import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
30 import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
31 import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanRequest;
32 import org.metricshub.ipmi.core.coding.payload.lan.NetworkFunction;
33 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
34 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
35 import org.metricshub.ipmi.core.coding.protocol.Ipmiv15Message;
36 import org.metricshub.ipmi.core.coding.security.CipherSuite;
37 import org.metricshub.ipmi.core.common.TypeConverter;
38
39 import java.security.InvalidKeyException;
40 import java.security.NoSuchAlgorithmException;
41 import java.util.ArrayList;
42
43
44
45
46 public class GetChannelAuthenticationCapabilities
47 extends IpmiCommandCoder<GetChannelAuthenticationCapabilitiesResponseData> {
48
49 private PrivilegeLevel requestedPrivilegeLevel;
50
51 private byte channelNumber;
52
53 private IpmiVersion requestVersion;
54
55 public void setRequestedPrivilegeLevel(PrivilegeLevel requestedPrivilegeLevel) {
56 this.requestedPrivilegeLevel = requestedPrivilegeLevel;
57 }
58
59 public PrivilegeLevel getRequestedPrivilegeLevel() {
60 return requestedPrivilegeLevel;
61 }
62
63
64
65
66
67
68
69
70
71
72 public void setChannelNumber(int channelNumber) {
73 if (channelNumber < 0 || channelNumber > 0xF || channelNumber == 0xC || channelNumber == 0xD) {
74 throw new IllegalArgumentException("Invalid channel number");
75 }
76 this.channelNumber = TypeConverter.intToByte(channelNumber);
77 }
78
79 public int getChannelNumber() {
80 return TypeConverter.byteToInt(channelNumber);
81 }
82
83 protected void setRequestVersion(IpmiVersion requestVersion) {
84 this.requestVersion = requestVersion;
85 }
86
87 protected IpmiVersion getRequestVersion() {
88 return requestVersion;
89 }
90
91
92
93
94
95
96
97
98
99
100
101 public GetChannelAuthenticationCapabilities() {
102 super();
103 setRequestedPrivilegeLevel(PrivilegeLevel.User);
104 setChannelNumber(14);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public GetChannelAuthenticationCapabilities(IpmiVersion version, IpmiVersion requestVersion,
124 CipherSuite cipherSuite) {
125 setSessionParameters(version, cipherSuite, AuthenticationType.None);
126 this.setRequestVersion(requestVersion);
127 setRequestedPrivilegeLevel(PrivilegeLevel.User);
128 setChannelNumber(14);
129 }
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 public GetChannelAuthenticationCapabilities(IpmiVersion version, IpmiVersion requestVersion, CipherSuite cipherSuite,
155 PrivilegeLevel privilegeLevel, byte channelNumber) {
156 setSessionParameters(version, cipherSuite, AuthenticationType.None);
157 this.setRequestVersion(requestVersion);
158 setRequestedPrivilegeLevel(privilegeLevel);
159 setChannelNumber(channelNumber);
160 }
161
162 @Override
163 public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId)
164 throws InvalidKeyException,
165 NoSuchAlgorithmException {
166 if (getIpmiVersion() == IpmiVersion.V15) {
167 if (sessionId != 0) {
168 throw new IllegalArgumentException("Session ID must be 0");
169 }
170
171 Ipmiv15Message message = new Ipmiv15Message();
172
173 message.setAuthenticationType(getAuthenticationType());
174
175 message.setSessionSequenceNumber(0);
176
177 message.setSessionID(0);
178
179 message.setPayload(preparePayload(messageSequenceNumber));
180
181 return message;
182 } else {
183 setAuthenticationType(AuthenticationType.RMCPPlus);
184
185 return super.encodePayload(messageSequenceNumber, sessionSequenceNumber, sessionId);
186 }
187 }
188
189 @Override
190 protected IpmiPayload preparePayload(int sequenceNumber) {
191 byte[] payload = new byte[2];
192
193 payload[0] = 0;
194
195 if (getRequestVersion() == IpmiVersion.V20) {
196 payload[0] |= TypeConverter.intToByte(0x80);
197 }
198
199 payload[0] |= channelNumber;
200
201 payload[1] = encodePrivilegeLevel(requestedPrivilegeLevel);
202 return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), payload, TypeConverter.intToByte(sequenceNumber));
203 }
204
205 @Override
206 public byte getCommandCode() {
207 return CommandCodes.GET_CHANNEL_AUTHENTICATION_CAPABILITIES;
208 }
209
210 @Override
211 public NetworkFunction getNetworkFunction() {
212 return NetworkFunction.ApplicationRequest;
213 }
214
215 @Override
216 public GetChannelAuthenticationCapabilitiesResponseData getResponseData(IpmiMessage message) throws IPMIException {
217 byte[] raw = validateResponse(message);
218
219 GetChannelAuthenticationCapabilitiesResponseData responseData = new GetChannelAuthenticationCapabilitiesResponseData();
220
221 if (raw.length != 8) {
222 throw new IllegalArgumentException("Data has invalid length");
223 }
224
225 responseData.setChannelNumber(raw[0]);
226
227
228
229 responseData.setIpmiv20Support((raw[1] & 0x80) != 0 && (raw[3] & 0x02) != 0);
230
231 responseData.setAuthenticationTypes(new ArrayList<AuthenticationType>());
232
233 if ((raw[1] & 0x20) != 0) {
234 responseData.getAuthenticationTypes().add(AuthenticationType.Oem);
235 }
236
237 if ((raw[1] & 0x10) != 0) {
238 responseData.getAuthenticationTypes().add(AuthenticationType.Simple);
239 }
240
241 if ((raw[1] & 0x04) != 0) {
242 responseData.getAuthenticationTypes().add(AuthenticationType.Md5);
243 }
244
245 if ((raw[1] & 0x02) != 0) {
246 responseData.getAuthenticationTypes().add(AuthenticationType.Md2);
247 }
248
249 if ((raw[1] & 0x01) != 0) {
250 responseData.getAuthenticationTypes().add(AuthenticationType.None);
251 }
252
253 responseData.setKgEnabled((raw[2] & 0x20) != 0);
254
255 responseData.setPerMessageAuthenticationEnabled((raw[2] & 0x10) == 0);
256
257 responseData.setUserLevelAuthenticationEnabled((raw[2] & 0x08) == 0);
258
259 responseData.setNonNullUsernamesEnabled((raw[2] & 0x04) != 0);
260
261 responseData.setNullUsernamesEnabled((raw[2] & 0x02) != 0);
262
263 responseData.setAnonymusLoginEnabled((raw[2] & 0x01) != 0);
264
265 byte[] oemId = new byte[4];
266
267 System.arraycopy(raw, 4, oemId, 0, 3);
268
269 oemId[3] = 0;
270
271 responseData.setOemId(TypeConverter.littleEndianByteArrayToInt(oemId));
272
273 responseData.setOemData(raw[7]);
274
275 return responseData;
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289 @Override
290 public void setSessionParameters(
291 IpmiVersion version,
292 CipherSuite cipherSuite,
293 AuthenticationType authenticationType) {
294
295 if (version == IpmiVersion.V20
296 && authenticationType != AuthenticationType.RMCPPlus
297 && authenticationType != AuthenticationType.None) {
298 throw new IllegalArgumentException("Authentication Type must be RMCPPlus for IPMI v2.0 messages");
299 }
300
301 setIpmiVersion(version);
302 setAuthenticationType(authenticationType);
303 setCipherSuite(cipherSuite);
304 }
305
306 }