1 package org.metricshub.ipmi.core.sm.states;
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.Encoder;
26 import org.metricshub.ipmi.core.coding.commands.session.GetChannelCipherSuites;
27 import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanResponse;
28 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
29 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
30 import org.metricshub.ipmi.core.coding.protocol.PayloadType;
31 import org.metricshub.ipmi.core.coding.protocol.decoder.ProtocolDecoder;
32 import org.metricshub.ipmi.core.coding.protocol.decoder.Protocolv20Decoder;
33 import org.metricshub.ipmi.core.coding.protocol.encoder.Protocolv20Encoder;
34 import org.metricshub.ipmi.core.coding.rmcp.RmcpMessage;
35 import org.metricshub.ipmi.core.coding.security.CipherSuite;
36 import org.metricshub.ipmi.core.common.TypeConverter;
37 import org.metricshub.ipmi.core.sm.StateMachine;
38 import org.metricshub.ipmi.core.sm.actions.ErrorAction;
39 import org.metricshub.ipmi.core.sm.actions.ResponseAction;
40 import org.metricshub.ipmi.core.sm.events.DefaultAck;
41 import org.metricshub.ipmi.core.sm.events.GetChannelCipherSuitesPending;
42 import org.metricshub.ipmi.core.sm.events.StateMachineEvent;
43 import org.metricshub.ipmi.core.sm.events.Timeout;
44
45
46
47
48
49
50
51 public class CiphersWaiting extends State {
52
53 private int index;
54
55 private int tag;
56
57
58
59
60
61
62
63
64
65 public CiphersWaiting(int index, int tag) {
66 this.index = index;
67 this.tag = tag;
68 }
69
70 @Override
71 public void doTransition(StateMachine stateMachine,
72 StateMachineEvent machineEvent) {
73 if (machineEvent instanceof Timeout) {
74 stateMachine.setCurrent(new Uninitialized());
75 } else if (machineEvent instanceof GetChannelCipherSuitesPending) {
76 GetChannelCipherSuitesPending event = (GetChannelCipherSuitesPending) machineEvent;
77 GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites(
78 TypeConverter.intToByte(0xE),
79 TypeConverter.intToByte(index + 1));
80 try {
81 tag = event.getSequenceNumber();
82 stateMachine.sendMessage(Encoder.encode(
83 new Protocolv20Encoder(), cipherSuites,
84 event.getSequenceNumber(), 0, 0));
85 ++index;
86 } catch (Exception e) {
87 stateMachine.doExternalAction(new ErrorAction(e));
88 }
89 } else if (machineEvent instanceof DefaultAck) {
90 stateMachine.setCurrent(new Ciphers());
91 } else {
92 stateMachine.doExternalAction(new ErrorAction(
93 new IllegalArgumentException("Invalid transition")));
94 }
95 }
96
97 @Override
98 public void doAction(StateMachine stateMachine, RmcpMessage message) {
99 if(ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) {
100 return;
101 }
102 if(Protocolv20Decoder.decodeSessionID(message) != 0){
103 return;
104 }
105 if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Ipmi) {
106 return;
107 }
108 Protocolv20Decoder decoder = new Protocolv20Decoder(
109 CipherSuite.getEmpty());
110 if(decoder.decodeAuthentication(message.getData()[1])) {
111 return;
112 }
113 IpmiMessage ipmiMessage = null;
114 try {
115 ipmiMessage = decoder.decode(message);
116 GetChannelCipherSuites suites = new GetChannelCipherSuites();
117 if (suites.isCommandResponse(ipmiMessage)
118 && TypeConverter.byteToInt(((IpmiLanResponse) ipmiMessage
119 .getPayload()).getSequenceNumber()) == tag) {
120 stateMachine.doExternalAction(new ResponseAction(suites
121 .getResponseData(ipmiMessage)));
122 }
123 } catch (Exception e) {
124 stateMachine.doExternalAction(new ErrorAction(e));
125 }
126 }
127
128 }