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.IpmiCommandCoder;
26 import org.metricshub.ipmi.core.coding.commands.IpmiVersion;
27 import org.metricshub.ipmi.core.coding.commands.PrivilegeLevel;
28 import org.metricshub.ipmi.core.coding.commands.ResponseData;
29 import org.metricshub.ipmi.core.coding.payload.CompletionCode;
30 import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
31 import org.metricshub.ipmi.core.coding.payload.PlainMessage;
32 import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
33 import org.metricshub.ipmi.core.coding.payload.lan.NetworkFunction;
34 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
35 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
36 import org.metricshub.ipmi.core.coding.protocol.Ipmiv20Message;
37 import org.metricshub.ipmi.core.coding.protocol.PayloadType;
38 import org.metricshub.ipmi.core.coding.security.AuthenticationAlgorithm;
39 import org.metricshub.ipmi.core.coding.security.CipherSuite;
40 import org.metricshub.ipmi.core.coding.security.ConfidentialityAlgorithm;
41 import org.metricshub.ipmi.core.coding.security.ConfidentialityNone;
42 import org.metricshub.ipmi.core.coding.security.IntegrityAlgorithm;
43 import org.metricshub.ipmi.core.common.TypeConverter;
44
45
46
47
48 public class OpenSession extends IpmiCommandCoder {
49
50 private PrivilegeLevel requestedPrivilegeLevel;
51
52
53
54
55 private int sessionID;
56
57 public void setRequestedPrivilegeLevel(
58 PrivilegeLevel requestedPrivilegeLevel) {
59 this.requestedPrivilegeLevel = requestedPrivilegeLevel;
60 }
61
62 public PrivilegeLevel getRequestedPrivilegeLevel() {
63 return requestedPrivilegeLevel;
64 }
65
66 private byte getRequestedPrivilegeLevelEncoded() {
67 switch (requestedPrivilegeLevel) {
68 case MaximumAvailable:
69 return 0;
70 case Callback:
71 return TypeConverter.intToByte(0x1);
72 case User:
73 return TypeConverter.intToByte(0x2);
74 case Operator:
75 return TypeConverter.intToByte(0x3);
76 case Administrator:
77 return TypeConverter.intToByte(0x4);
78 default:
79 throw new IllegalArgumentException("Invalid privilege level");
80 }
81 }
82
83 public void setSessionID(int sessionID) {
84 this.sessionID = sessionID;
85 }
86
87 public int getSessionID() {
88 return sessionID;
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 public OpenSession(CipherSuite cipherSuite) {
106 super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus);
107 setCipherSuite(cipherSuite);
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 public OpenSession(int sessionID, PrivilegeLevel privilegeLevel,
134 CipherSuite cipherSuite) {
135 super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus);
136
137 setSessionID(sessionID);
138 setRequestedPrivilegeLevel(privilegeLevel);
139 }
140
141 @Override
142 public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) {
143 if (sessionId != 0) {
144 throw new IllegalArgumentException("Session ID must be 0");
145 }
146 Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone());
147
148 message.setPayloadType(PayloadType.RmcpOpenSessionRequest);
149 message.setSessionID(0);
150 message.setSessionSequenceNumber(0);
151 message.setAuthenticationType(getAuthenticationType());
152 message.setPayloadAuthenticated(false);
153 message.setPayloadEncrypted(false);
154 message.setPayload(preparePayload(messageSequenceNumber));
155
156 return message;
157 }
158
159 @Override
160 protected IpmiPayload preparePayload(int sequenceNumber) {
161 byte[] payload = new byte[32];
162
163 payload[0] = TypeConverter.intToByte(sequenceNumber);
164
165 payload[1] = getRequestedPrivilegeLevelEncoded();
166
167 payload[2] = 0;
168 payload[3] = 0;
169
170
171 byte[] id = TypeConverter.intToLittleEndianByteArray(sessionID);
172
173 System.arraycopy(id, 0, payload, 4, 4);
174
175
176
177 payload[8] = 0;
178 payload[9] = 0;
179 payload[10] = 0;
180 payload[11] = 0x08;
181 payload[12] = getCipherSuite().getAuthenticationAlgorithm().getCode();
182
183
184
185 payload[13] = 0;
186 payload[14] = 0;
187 payload[15] = 0;
188
189
190
191 payload[16] = 0x01;
192 payload[17] = 0;
193 payload[18] = 0;
194 payload[19] = 0x08;
195 payload[20] = getCipherSuite().getIntegrityAlgorithm().getCode();
196
197
198
199 payload[21] = 0;
200 payload[22] = 0;
201 payload[23] = 0;
202
203
204
205 payload[24] = 0x02;
206 payload[25] = 0;
207 payload[26] = 0;
208 payload[27] = 0x08;
209 payload[28] = getCipherSuite().getConfidentialityAlgorithm().getCode();
210
211
212
213 payload[29] = 0;
214 payload[30] = 0;
215 payload[31] = 0;
216
217 return new PlainMessage(payload);
218 }
219
220 @Override
221 public NetworkFunction getNetworkFunction() {
222 return NetworkFunction.ChassisRequest;
223 }
224
225 @Override
226 public byte getCommandCode() {
227 return 0;
228 }
229
230 @Override
231 public ResponseData getResponseData(IpmiMessage message) throws IPMIException {
232 if (!isCommandResponse(message)) {
233 throw new IllegalArgumentException(
234 "This is not a response for Open Session command");
235 }
236
237 byte[] payload = message.getPayload().getPayloadData();
238
239 if (payload[1] != 0) {
240 throw new IPMIException(CompletionCode.parseInt(TypeConverter
241 .byteToInt(payload[1])));
242 }
243
244 if (payload.length < 36) {
245 throw new IllegalArgumentException("Invalid payload length");
246 }
247
248 OpenSessionResponseData data = new OpenSessionResponseData();
249
250 data.setMessageTag(payload[0]);
251
252 data.setStatusCode(payload[1]);
253
254 data.setPrivilegeLevel(payload[2]);
255
256 byte[] buffer = new byte[4];
257
258 System.arraycopy(payload, 4, buffer, 0, 4);
259
260 data.setRemoteConsoleSessionId(TypeConverter
261 .littleEndianByteArrayToInt(buffer));
262
263 System.arraycopy(payload, 8, buffer, 0, 4);
264
265 data.setManagedSystemSessionId(TypeConverter
266 .littleEndianByteArrayToInt(buffer));
267
268 byte[] auth = new byte[8];
269
270 System.arraycopy(payload, 12, auth, 0, 8);
271
272 data.setAuthenticationAlgorithm(auth[4]);
273
274 byte[] integr = new byte[8];
275
276 System.arraycopy(payload, 20, integr, 0, 8);
277
278 data.setIntegrityAlgorithm(integr[4]);
279
280 byte[] conf = new byte[8];
281
282 System.arraycopy(payload, 28, conf, 0, 8);
283
284 data.setConfidentialityAlgorithm(conf[4]);
285
286 return data;
287 }
288
289 }