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