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.PayloadCoder;
27 import org.metricshub.ipmi.core.coding.commands.IpmiVersion;
28 import org.metricshub.ipmi.core.coding.commands.session.CloseSession;
29 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
30 import org.metricshub.ipmi.core.coding.protocol.Ipmiv20Message;
31 import org.metricshub.ipmi.core.coding.protocol.PayloadType;
32 import org.metricshub.ipmi.core.coding.protocol.decoder.ProtocolDecoder;
33 import org.metricshub.ipmi.core.coding.protocol.decoder.Protocolv20Decoder;
34 import org.metricshub.ipmi.core.coding.protocol.encoder.Protocolv20Encoder;
35 import org.metricshub.ipmi.core.coding.rmcp.RmcpMessage;
36 import org.metricshub.ipmi.core.coding.security.CipherSuite;
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.MessageAction;
40 import org.metricshub.ipmi.core.sm.events.Sendv20Message;
41 import org.metricshub.ipmi.core.sm.events.StateMachineEvent;
42 import org.metricshub.ipmi.core.sm.events.Timeout;
43
44
45
46
47
48
49
50
51
52
53
54
55 public class SessionValid extends State {
56
57 private CipherSuite cipherSuite;
58
59 private int sessionId;
60
61 public CipherSuite getCipherSuite() {
62 return cipherSuite;
63 }
64
65
66
67
68
69
70
71 public SessionValid(CipherSuite cipherSuite, int sessionId) {
72 this.cipherSuite = cipherSuite;
73 this.sessionId = sessionId;
74 }
75
76 @Override
77 public void doTransition(StateMachine stateMachine, StateMachineEvent machineEvent) {
78 if (machineEvent instanceof Sendv20Message) {
79 Sendv20Message event = (Sendv20Message) machineEvent;
80 try {
81 stateMachine.sendMessage(encode(event));
82 } catch (Exception e) {
83 stateMachine.doExternalAction(new ErrorAction(e));
84 }
85 } else if (machineEvent instanceof Timeout) {
86 stateMachine.setCurrent(new Authcap());
87 } else if (machineEvent instanceof org.metricshub.ipmi.core.sm.events.CloseSession) {
88 org.metricshub.ipmi.core.sm.events.CloseSession event = (org.metricshub.ipmi.core.sm.events.CloseSession) machineEvent;
89
90 try {
91 stateMachine.setCurrent(new Authcap());
92 stateMachine.sendMessage(
93 Encoder.encode(
94 new Protocolv20Encoder(),
95 closeSession(event.getSessionId()),
96 event.getMessageSequenceNumber(),
97 event.getSessionSequenceNumber(),
98 event.getSessionId()));
99 } catch (Exception e) {
100 stateMachine.setCurrent(this);
101 stateMachine.doExternalAction(new ErrorAction(e));
102 }
103 } else {
104 stateMachine.doExternalAction(new ErrorAction(new IllegalArgumentException("Invalid transition")));
105 }
106
107 }
108
109
110
111
112
113
114 private byte[] encode(Sendv20Message event) throws Exception {
115 PayloadCoder coder = event.getPayloadCoder();
116 synchronized (coder) {
117 coder.setSessionParameters(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus);
118 return Encoder.encode(
119 new Protocolv20Encoder(),
120 coder,
121 event.getMessageSequenceNumber(),
122 event.getSessionSequenceNumber(),
123 event.getSessionId());
124 }
125 }
126
127 private CloseSession closeSession(int closedSessionId) {
128 CloseSession closeSession = new CloseSession(closedSessionId);
129 closeSession.setSessionParameters(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus);
130 return closeSession;
131 }
132
133 @Override
134 public void doAction(StateMachine stateMachine, RmcpMessage message) {
135 if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) {
136 return;
137 }
138 if (Protocolv20Decoder.decodeSessionID(message) == 0) {
139 return;
140 }
141 Protocolv20Decoder decoder = new Protocolv20Decoder(cipherSuite);
142 PayloadType payloadType = Protocolv20Decoder.decodePayloadType(message.getData()[1]);
143
144 if (payloadType != PayloadType.Ipmi && payloadType != PayloadType.Sol) {
145 return;
146 }
147 if (Protocolv20Decoder.decodeSessionID(message) != sessionId) {
148 return;
149 }
150 try {
151 Ipmiv20Message message20 = (Ipmiv20Message) decoder.decode(message);
152 if (message20.getSessionID() == sessionId) {
153 stateMachine.doExternalAction(new MessageAction(message20));
154 }
155 } catch (Exception e) {
156
157
158 }
159 }
160
161 }