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