1 package org.metricshub.ipmi.core.connection;
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.api.async.ConnectionHandle;
26 import org.metricshub.ipmi.core.api.sol.CipherSuiteSelectionHandler;
27 import org.metricshub.ipmi.core.api.sync.IpmiConnector;
28 import org.metricshub.ipmi.core.coding.commands.PrivilegeLevel;
29 import org.metricshub.ipmi.core.coding.security.CipherSuite;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import java.net.InetAddress;
35 import java.util.List;
36 import java.util.concurrent.ConcurrentHashMap;
37
38
39
40
41 public class SessionManager {
42
43 private static final Logger logger = LoggerFactory.getLogger(SessionManager.class);
44
45 private static Integer sessionId = 100;
46
47
48
49
50
51 public static synchronized int generateSessionId() {
52 sessionId %= (Integer.MAX_VALUE / 4);
53 return sessionId++;
54 }
55
56 public static Session establishSession(IpmiConnector connector, String remoteHost, int remotePort, String user, String password,
57 CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SessionException {
58 ConnectionHandle handle = null;
59
60 try {
61 handle = connector.createConnection(InetAddress.getByName(remoteHost), remotePort);
62
63 List<CipherSuite> availableCipherSuites = connector.getAvailableCipherSuites(handle);
64 CipherSuite cipherSuite = cipherSuiteSelectionHandler.choose(availableCipherSuites);
65
66 if (cipherSuite == null) {
67 cipherSuite = CipherSuite.getEmpty();
68 }
69
70 connector.getChannelAuthenticationCapabilities(handle, cipherSuite, PrivilegeLevel.Administrator);
71
72 return connector.openSession(handle, user, password, null);
73 } catch (Exception e) {
74 closeConnection(connector, handle);
75
76 throw new SessionException("Cannot create new session due to exception", e);
77 }
78 }
79
80 private static void closeConnection(IpmiConnector connector, ConnectionHandle handle) {
81 try {
82 if (connector != null && handle != null) {
83 connector.closeSession(handle);
84 connector.tearDown();
85 }
86 } catch (Exception e) {
87 logger.error("Cannot close connection after exception thrown during session establishment.", e);
88 }
89 }
90
91 private final ConcurrentHashMap<Integer, Session> sessionsPerConnectionHandle;
92
93 public SessionManager() {
94 this.sessionsPerConnectionHandle = new ConcurrentHashMap<Integer, Session>();
95 }
96
97
98
99
100
101
102
103
104
105 public Session registerSession(int sessionId, ConnectionHandle connectionHandle) {
106 if (connectionHandle.getUser() == null || connectionHandle.getRemoteAddress() == null) {
107 throw new IllegalArgumentException("Given connection handle is incomplete (lacks user or remote address)");
108 }
109
110 Session newSession = new Session(sessionId, connectionHandle);
111 Session currentSession = sessionsPerConnectionHandle.putIfAbsent(connectionHandle.getHandle(), newSession);
112
113 return currentSession != null ? currentSession : newSession;
114 }
115
116
117
118
119
120
121
122 public void unregisterSession(ConnectionHandle connectionHandle) {
123 sessionsPerConnectionHandle.remove(connectionHandle.getHandle());
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137 public Session getSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) {
138 for (Session session : sessionsPerConnectionHandle.values()) {
139 ConnectionHandle sessionConnectionHandle = session.getConnectionHandle();
140
141 if (sessionConnectionHandle.getUser().equals(user)
142 && sessionConnectionHandle.getRemoteAddress().equals(remoteAddress)
143 && sessionConnectionHandle.getRemotePort() == remotePort) {
144 return session;
145 }
146 }
147
148 return null;
149 }
150 }