Cuberite
A lightweight, fast and extensible game server for Minecraft
LuaTCPLink.cpp
Go to the documentation of this file.
1 
2 // LuaTCPLink.cpp
3 
4 // Implements the cLuaTCPLink class representing a Lua wrapper for the cTCPLink class and the callbacks it needs
5 
6 #include "Globals.h"
7 #include "LuaTCPLink.h"
8 #include "LuaServerHandle.h"
9 #include "../mbedTLS++/X509Cert.h"
10 #include "../mbedTLS++/CryptoKey.h"
11 
12 
13 
14 
15 
17  m_Callbacks(std::move(a_Callbacks))
18 {
19 }
20 
21 
22 
23 
24 
26  m_Callbacks(std::move(a_Callbacks)),
27  m_Server(std::move(a_ServerHandle))
28 {
29 }
30 
31 
32 
33 
34 
36 {
37  // If the link is still open, close it:
38  auto link = m_Link;
39  if (link != nullptr)
40  {
41  link->Close();
42  }
43 
44  Terminated();
45 }
46 
47 
48 
49 
50 
51 bool cLuaTCPLink::Send(const AString & a_Data)
52 {
53  // Safely grab a copy of the link:
54  auto link = m_Link;
55  if (link == nullptr)
56  {
57  return false;
58  }
59 
60  // Send the data:
61  return link->Send(a_Data);
62 }
63 
64 
65 
66 
67 
69 {
70  // Safely grab a copy of the link:
71  auto link = m_Link;
72  if (link == nullptr)
73  {
74  return "";
75  }
76 
77  // Get the IP address:
78  return link->GetLocalIP();
79 }
80 
81 
82 
83 
84 
86 {
87  // Safely grab a copy of the link:
88  auto link = m_Link;
89  if (link == nullptr)
90  {
91  return 0;
92  }
93 
94  // Get the port:
95  return link->GetLocalPort();
96 }
97 
98 
99 
100 
101 
103 {
104  // Safely grab a copy of the link:
105  cTCPLinkPtr link = m_Link;
106  if (link == nullptr)
107  {
108  return "";
109  }
110 
111  // Get the IP address:
112  return link->GetRemoteIP();
113 }
114 
115 
116 
117 
118 
120 {
121  // Safely grab a copy of the link:
122  cTCPLinkPtr link = m_Link;
123  if (link == nullptr)
124  {
125  return 0;
126  }
127 
128  // Get the port:
129  return link->GetRemotePort();
130 }
131 
132 
133 
134 
135 
137 {
138  // Safely grab a copy of the link and shut it down:
139  cTCPLinkPtr link = m_Link;
140  if (link != nullptr)
141  {
142  link->Shutdown();
143  }
144 }
145 
146 
147 
148 
149 
151 {
152  // If the link is still open, close it:
153  cTCPLinkPtr link = m_Link;
154  if (link != nullptr)
155  {
156  link->Close();
157  }
158 
159  Terminated();
160 }
161 
162 
163 
164 
165 
167  const AString & a_OwnCertData,
168  const AString & a_OwnPrivKeyData,
169  const AString & a_OwnPrivKeyPassword,
170  const AString & a_TrustedRootCAs
171 )
172 {
173  auto link = m_Link;
174  if (link != nullptr)
175  {
176  cX509CertPtr ownCert;
177  if (!a_OwnCertData.empty())
178  {
179  ownCert = std::make_shared<cX509Cert>();
180  auto res = ownCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
181  if (res != 0)
182  {
183  return fmt::format(FMT_STRING("Cannot parse client certificate: -0x{:x}"), -res);
184  }
185  }
186  cCryptoKeyPtr ownPrivKey;
187  if (!a_OwnPrivKeyData.empty())
188  {
189  ownPrivKey = std::make_shared<cCryptoKey>();
190  auto res = ownPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
191  if (res != 0)
192  {
193  return fmt::format(FMT_STRING("Cannot parse client private key: -0x{:x}"), -res);
194  }
195  }
196 
197  cX509CertPtr trustedRootCAs;
198  if (!a_TrustedRootCAs.empty())
199  {
200  trustedRootCAs = std::make_shared<cX509Cert>();
201  auto res = trustedRootCAs->Parse(a_TrustedRootCAs.data(), a_TrustedRootCAs.size());
202  if (res != 0)
203  {
204  return fmt::format("Cannot parse trusted root CAs: {}", res);
205  }
206  }
207  return link->StartTLSClient(ownCert, ownPrivKey, trustedRootCAs);
208  }
209  return "";
210 }
211 
212 
213 
214 
215 
217  const AString & a_OwnCertData,
218  const AString & a_OwnPrivKeyData,
219  const AString & a_OwnPrivKeyPassword,
220  const AString & a_StartTLSData
221 )
222 {
223  auto link = m_Link;
224  if (link != nullptr)
225  {
226  // Create the peer cert:
227  auto OwnCert = std::make_shared<cX509Cert>();
228  int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
229  if (res != 0)
230  {
231  return fmt::format(FMT_STRING("Cannot parse server certificate: -0x{:x}"), -res);
232  }
233  auto OwnPrivKey = std::make_shared<cCryptoKey>();
234  res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
235  if (res != 0)
236  {
237  return fmt::format(FMT_STRING("Cannot parse server private key: -0x{:x}"), -res);
238  }
239 
240  return link->StartTLSServer(OwnCert, OwnPrivKey, a_StartTLSData);
241  }
242  return "";
243 }
244 
245 
246 
247 
248 
250 {
251  // Disable the callbacks:
252  if (m_Callbacks->IsValid())
253  {
254  m_Callbacks->Clear();
255  }
256 
257  // If the managing server is still alive, let it know we're terminating:
258  auto Server = m_Server.lock();
259  if (Server != nullptr)
260  {
261  Server->RemoveLink(this);
262  }
263 
264  // If the link is still open, close it:
265  {
266  auto link= m_Link;
267  if (link != nullptr)
268  {
269  link->Close();
270  m_Link.reset();
271  }
272  }
273 }
274 
275 
276 
277 
278 
279 void cLuaTCPLink::ReceivedCleartextData(const char * a_Data, size_t a_NumBytes)
280 {
281  // Call the callback:
282  m_Callbacks->CallTableFn("OnReceivedData", this, AString(a_Data, a_NumBytes));
283 }
284 
285 
286 
287 
288 
290 {
291  // Call the callback:
292  m_Callbacks->CallTableFn("OnConnected", this);
293 }
294 
295 
296 
297 
298 
299 void cLuaTCPLink::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
300 {
301  // Call the callback:
302  m_Callbacks->CallTableFn("OnError", this, a_ErrorCode, a_ErrorMsg);
303 
304  // Terminate all processing on the link:
305  Terminated();
306 }
307 
308 
309 
310 
311 
313 {
314  // Store the cTCPLink for later use:
315  m_Link = a_Link;
316 }
317 
318 
319 
320 
321 
322 void cLuaTCPLink::OnReceivedData(const char * a_Data, size_t a_Length)
323 {
324  // Call the callback:
325  m_Callbacks->CallTableFn("OnReceivedData", this, AString(a_Data, a_Length));
326 }
327 
328 
329 
330 
331 
333 {
334  // Call the callback:
335  m_Callbacks->CallTableFn("OnRemoteClosed", this);
336 
337  // Terminate all processing on the link:
338  Terminated();
339 }
340 
341 
342 
343 
344 
std::weak_ptr< cLuaServerHandle > cLuaServerHandleWPtr
Definition: LuaTCPLink.h:20
unsigned short UInt16
Definition: Globals.h:158
std::shared_ptr< cCryptoKey > cCryptoKeyPtr
Definition: CryptoKey.h:72
std::shared_ptr< cX509Cert > cX509CertPtr
Definition: SslConfig.h:13
std::shared_ptr< cTCPLink > cTCPLinkPtr
Definition: Network.h:25
std::string AString
Definition: StringUtils.h:11
Definition: FastNBT.h:132
std::unique_ptr< cTableRef > cTableRefPtr
Definition: LuaState.h:419
UInt16 GetRemotePort(void) const
Returns the port used by the remote endpoint of the connection.
Definition: LuaTCPLink.cpp:119
cLuaServerHandleWPtr m_Server
The server that is responsible for this link, if any.
Definition: LuaTCPLink.h:103
virtual void OnReceivedData(const char *a_Data, size_t a_Length) override
Called when there's data incoming from the remote peer.
Definition: LuaTCPLink.cpp:322
AString GetLocalIP(void) const
Returns the IP address of the local endpoint of the connection.
Definition: LuaTCPLink.cpp:68
cLuaTCPLink(cLuaState::cTableRefPtr &&a_Callbacks)
Creates a new instance of the link, wrapping the callbacks that are in the specified table.
Definition: LuaTCPLink.cpp:16
bool Send(const AString &a_Data)
Sends the data contained in the string to the remote peer.
Definition: LuaTCPLink.cpp:51
AString StartTLSClient(const AString &a_OwnCertData, const AString &a_OwnPrivKeyData, const AString &a_OwnPrivKeyPassword, const AString &a_TrustedRootCAs)
Starts a TLS handshake as a client connection.
Definition: LuaTCPLink.cpp:166
virtual void OnError(int a_ErrorCode, const AString &a_ErrorMsg) override
Called when an error is detected on the connection.
Definition: LuaTCPLink.cpp:299
virtual void OnRemoteClosed(void) override
Called when the remote end closes the connection.
Definition: LuaTCPLink.cpp:332
void Close(void)
Drops the connection without any more processing.
Definition: LuaTCPLink.cpp:150
void ReceivedCleartextData(const char *a_Data, size_t a_NumBytes)
Called by the SSL context when there's incoming data available in the cleartext.
Definition: LuaTCPLink.cpp:279
AString StartTLSServer(const AString &a_OwnCertData, const AString &a_OwnPrivKeyData, const AString &a_OwnPrivKeyPassword, const AString &a_StartTLSData)
Starts a TLS handshake as a server connection.
Definition: LuaTCPLink.cpp:216
void Terminated(void)
Common code called when the link is considered as terminated.
Definition: LuaTCPLink.cpp:249
cLuaState::cTableRefPtr m_Callbacks
The Lua table that holds the callbacks to be invoked.
Definition: LuaTCPLink.h:96
virtual void OnConnected(cTCPLink &a_Link) override
Called when the Connect call succeeds.
Definition: LuaTCPLink.cpp:289
AString GetRemoteIP(void) const
Returns the IP address of the remote endpoint of the connection.
Definition: LuaTCPLink.cpp:102
void Shutdown(void)
Closes the link gracefully.
Definition: LuaTCPLink.cpp:136
virtual void OnLinkCreated(cTCPLinkPtr a_Link) override
Called when the cTCPLink for the connection is created.
Definition: LuaTCPLink.cpp:312
cTCPLinkPtr m_Link
The underlying link representing the connection.
Definition: LuaTCPLink.h:100
UInt16 GetLocalPort(void) const
Returns the port used by the local endpoint of the connection.
Definition: LuaTCPLink.cpp:85
virtual ~cLuaTCPLink() override
Definition: LuaTCPLink.cpp:35
Interface that provides the methods available on a single TCP connection.
Definition: Network.h:42